9 ms·
Write code like a human will maintain it
- secondcupofchai 2mo agoI think we have to accept the innovation, adapt to new reality and use it to our advantage, my 2 cents on this.
- ge96 2mo agoBeen getting these vibe coded PRs ugh code PR submitter can't even explain
- tristan666 2mo agou right
- alexpotato 2mo agoThere is an old quote: "Add comments to your code under the assumption that the next person to maintain it is a homicidal maniac who knows where you live"
- hansonkd 2mo agoThe comments that drive the most homicidal behavior are outdated or inaccurate comments rather than no comments.
- minraws 2mo agoBoth can be true at the same time, we can be equal opportunity murderers who treat lazy verbosity and hippester terse code.
- gowld 2mo agoPut your home address in the comments. Problem solved.
- sejje 2mo agoI moved after I wrote the comment. It's hard to keep everything up to date.
- saghm 2mo agoSure, but the proportion of code that drives homicidal behavior is heavily weighted towards non-comments. You're a lot more likely to piss off whoever inherits your code with the code that actually does something being bad or a lack of documentation than with comments.
- jraph 2mo agoI'm quite fine with no comments but correctly named variables and functions. This can't become out of sync contrarily to "out of band" comments. I take this over commented code with poorly named stuff any day. I've also seen a lot of comments that restate what the code already says and that's just noise, more work to keep in sync, an additional thing that can fail, and more cognitive load because you have to read twice the same thing (best case, if code and comment are still in sync). That's the result you risk when you think you must comment your code. I appreciate the occasional comment that explains why something seems overly tricky or weird or not immediately intuitive. Once, I had left such a comment that saved myself years later from making a mistake. Of course, this should be kept at a minimal level. It leads to me liking clear code with few comments the most. (Some guidelines, even if it's not perfect, to limit complexity and spaghetti code help a lot). Function, class, module documentation is also useful so you don't have to read the whole thing and you know what it's intended to provide (which is slightly different than simply what it provides, and this differences is important).
- AnimalMuppet 2mo agoI worked with this guy. He'd write the code, and comment where needed, and then he would ask "How can I make this comment unnecessary?" The answer was usually to rename something, so that what he was doing was obvious.
- jraph 2mo agoNice, I love this. That's pretty satisfying.
- saghm 2mo ago
- TimTheTinker 2mo agoRight now the comments that upset me the most are LLM TMI-style comments that break encapsulation by talking about the behavior of specific current callers of a function right above the function definition. I recently reacted angrily in a PR review comment after encountering one for the umpteenth time... that caught me off guard. I didn't know I was capable of that.
- jawilson2 2mo agoYeah, agreed. These have started popping up a lot more recently, where I get a 5 sentence paragraph explaining how function overloading works in c++.
- fphilipe 2mo agoThis is what has been frustrating me most lately. Even though I have a rule in my global CLAUDE.md that says: > Only write comments to explain the why when it is not obvious from the code (rationale, gotchas, constraints). Do not comment on the what — well-named code already says it. Do not comment on how a framework works. It still keeps adding these bad comments. When I then ask it to review the comments based on my preferences it then deletes most of them or improves them. Today I asked Claude why it disrespects my preference and it said that the surrounding code was like that and it followed that style. It suggested I add this line to my global CLAUDE.md file: > The comment rule above beats the style of the surrounding code: neighboring files with what-style comments are not license to write more of them, and comments carried along when porting or copying code must be re-judged against the rule, not kept for consistency. Let's see if that improves things.
- mnicky 2mo agoIn Claude Code there are also "output styles" that are more deeply embedded - into a system prompt - and agent is also periodically reminded of them during the session: https://code.claude.com/docs/en/output-styles https://code.claude.com/docs/en/output-styles Maybe these would work better for such cases.
- 2mo ago
- deleted 2mo ago[deleted]
- SoftTalker 2mo agoUsed to work with a guy who would frequently say "a comment is an apology" i.e. the comment is there because the code itself is not clear. That can be the case, but I generally find more comments better than fewer, especially if they relate the code to actual business or functional requirements and don't just restate what the code is doing. Years ago I would often write comments first. I.e. start with describing the overall goals. Then break it down into routines and order of operations, all still in plain english. Once I was happy with that, I'd break up the comments with blocks of code. I guess this is sort of like "literate programming" though I was doing it long before I ever heard that term and I still have never read much about it. It's almost more like I was prompting myself towards the end goal. The downside of this approach is that the comments do end up more or less just explaining in english what the code is doing, so maybe aren't quite as useful to future maintainers.
- WillAdams 2mo agoI really wish Literate Programming had caught on. The big problem is folks misunderstood it as documentation (arguably plain.tex should have also been the sourcecode for _The TeXbook_ and that it wasn't is a big part of this) --- it could be, but usually that's better as a separate text/chapter.... I've been trying to collect books on Literate Program/notable Literate Programs published as books: https://www.goodreads.com/review/list/21394355-william-adams?ref=nav_mybooks&tag=literateprograms https://www.goodreads.com/review/list/21394355-william-adams... and I will note that my own programming took a quantum leap forward when I purchased and read: https://www.goodreads.com/book/show/39996759-a-philosophy-of-software-design https://www.goodreads.com/book/show/39996759-a-philosophy-of... and applied its principles one chapter at a time to a project which I was able (w/ a bit of help) to get into Literate Programming form: https://github.com/WillAdams/gcodepreview/blob/main/literati.sty https://github.com/WillAdams/gcodepreview/blob/main/literati...
- hakunin 2mo agoThere was a phase, which I also got sucked into at the time, that comments are bad. Problem is, to make your code be so self-explanatory that it conveys business decisions, background stories for how you've arrived here, research-based choices made, you would have to name your variables and functions in a batshit_insane_way_that_obfuscates_behavior_among_the_names. It doesn't make anything better. Use short names where they're contextually clear. Use long names where they're contextually weird/non-belonging. Use comments to explain the "whys" of your code.
- dionian 2mo agosounds like a recipe for over-commenting. The code should be self-documenting. Comments are for the places where there are dragons.
- Invictus0 2mo ago[flagged]
- klabb3 2mo agoWhy stop there? If you _use_ handwritten products you’re ngmi. I only use vibe coded operating systems, JavaScript sandboxes, compilers, TLS libraries, databases, rendering engines..
- tjwebbnorfolk 2mo agoThis is cute reductio ad absurdum, but it does nothing to refute the basic point made
- discreteevent 2mo agoThere was no point made. You couldn't find a shallower comment. Why are you even bothered to defend it?
- cyanydeez 2mo agoif your skillset is tied to corporate bullshit, yourre better off buying lottery tickets
- matt_kantor 2mo agoIf you don't understand the software you're creating (handwritten or not) you are ngmi.
- OtherShrezzing 2mo agoIt's unlikely that AI will get to the point where it makes handwritten coders redundant, and then not immediately be at the point where vibe coders are redundant too. So if you earnestly take the position that handwriting code is a "ngmi" type activity, you also need to take the position that the vibe coder (or agent- assisted-developer/loop-architect, or whatever its nom de guerre is this week) is "ngmi".
- cebert 2mo agoIt's interesting that the author didn't mention considering updating their agentic code review prompt to keep an eye out for repetitive/duplicate code.
- cyanydeez 2mo agoAI isnt taking my job. my company is supporting local AI for development. who ever comes after me will have the same hardware and models or better. unless a MBA is put in charge, my boss and predecessors can maintain and build out as needed. bottom up AI use seems a godsend compared to the corporate AI rat race. i setup some slop reporting systems and ensured my boss knows theyre great starting points but serious use requires real time investment.
- schnebbau 2mo agoThat sounds like a good idea, but shipping 10x as many features and bugfixes sounds better. I started using AI with the best intentions. Checking everything before committing. Improving output by hand if it didn't quite follow the existing code style guidelines or variables were not named as well as they should be. Or if it did something sloppy or hacky. Now, AI GOES BURRRRRRRRRRRR! If the tests pass it's good to ship. AI can deal with the problems it may create. No problems so far.
- matt_kantor 2mo agoHow long has "so far" been?
- pauletienney 2mo agoI second that question
- schnebbau 2mo agoSince November.
- AnimalMuppet 2mo agoYeah... in at least some circumstances, "maintainable" means, like, 20 years. 8 months is not an adequate test.
- hansonkd 2mo agoYeah, the flip side of the article is that Fable level models can fix the majority of codebases created from the past 3 years and one shot it to a fixable state that is "human maintainable"
- carimura 2mo agoI find myself doing this but then I worry that the slop will just compound and 3, 6, 12 months from now as my services scale I'll have a harder time operating them. Maybe I'm wrong.
- dsagent 2mo agoVery much this. LLMs are not producing code humans can maintain unless you take your time with them and still care about the quality of the output. Maybe someone has the perfect claude.md that solves this problem but I have not seen it.
- imhoguy 2mo agoCLAUDE.md (or AGENTS.md) is not good place to put all code change rules, because these rules would dillute the context and "distract" the agent e.g. during bugs triage or business analysis. Instead modularize the knowledge with skills and specialized MD files. Agent should lazy load what is needed to do focused work. Skills have usage description metadata, but with free files you can simply instruct agent with CLAUDE.md to load them, e.g.: "Before you attempt to change any frontend code first load and follow `docs/{JS|HTML|CSS}_coding_rules.md`".
- deadbabe 2mo agoI absolutely will not write corporate code like humans are maintaining it anymore, because I don’t have any confidence actual humans will be maintaining it. For personal projects, I can trust that I myself will be maintaining things so I still write things like it matters, but I do not extend the trust to others.
- bdcravens 2mo agoHumans have been writing unmaintainable code well before LLMs came along.
- BadBadJellyBean 2mo agoBut LLMs can do it much faster and more consistently.
- bdcravens 2mo agoThey had good teachers. :-)
- carimura 2mo agoI continually run codebases through different models to have them look for bad code smells like repeated code. That's been pretty effective. You do have to maintain over time or else you end up with a sloppy mess which I can only imagine compounds.
- deleted 2mo ago[deleted]
- sejje 2mo agoDo you think it matters that it's a different model? Or is it more about the review process and a context reset?
- bluGill 2mo agoI have personally not found value in a different model. The review itself often is good.
- carimura 2mo agoI don't have a scientific answer to this but I'm just assuming a different model, and more specifically, the frontier latest models like Fable/5.6 would catch things the author model might skip over.
- t-writescode 2mo agoWhat do you think of traditional AST-based static analyzers (like SonarQube, Rubocop, etc.) that catch cyclomatic complexity and code duplication deterministically? You can even put them on the build pipeline, even. No tokens spent at all!
- carimura 2mo agoI haven't used them but I'm sure they're good and I'm sure they're even using LLMs themselves now as a non-deterministic pass. For my use cases I'm just trying to keep vendors/costs to a minimum.
- andrewjneumann 2mo agoHave a bit of a contrarian view on this tl;dr don’t write code for human consumption if you use AI; BUT you have to accept AI coding lock in and change how you work. Funny enough, discussed this yesterday Stop Optimizing Code for Humans https://youtube.com/live/eLn4-XA-KdQ?feature=share https://youtube.com/live/eLn4-XA-KdQ?feature=share
- jdw64 2mo agoAlways code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. Code for readability. — John F. Woods (1991)
- ing33k 2mo agoAnd hope it works? I’m pretty sure many people who use AI to write emails or blog posts add "make it sound like a human wrote it" to their prompts. We all know what the result usually looks like. If AI is writing my code, I'd rather have it focus purely on correctness and efficiency than on making the code easy to read. heck! I might even ask it to imitate Arthur Whitney’s style. /s
- cadamsdotcom 2mo agoWrite yourself a /review command. That is an empty markdown file at `.claude/commands/review.md`. In it, put a checklist of things the agent should look for. When you’re ready to have your agent review the code, type `/review`. The checklist will be examined and it’ll plan out some findings to ask you if you want them fixed. Mine starts with “Enter plan mode. Examine the differences on this branch vs. main. Consider: ...” and proceeds to a bullet list of things. Any time I notice something in code review and have to get the agent to fix it.. I throw it on the list! My list is like 200 items now. Know what? Agents don’t care that they just got a wall of generic feedback, they happily look into all the bullet points. I added “ensure the new things aren’t duplicating code that already exists elsewhere” and it gave me such a surprise - it really truly started planning cleanups! We are just scratching the surface. We have to give tools to our tools so they can use them to be better tools for us.
- nextaccountic 2mo agoJust one thing A model might be able to follow 200 different instructions at the same time, while another model will choke on it
- cadamsdotcom 2mo agoYes and this is a really important point. I actually have no data on how other models do - feeling very spoiled by Claude to be honest. Would love to hear how it goes if you try it with other models!
- jhghbj 2mo ago[dead]
- deleted 2mo ago[deleted]
- ebiester 2mo agoYou should do an experiment of splitting that up to multiple reviews that are logically together. My hypothesis is that you may be losing signal due to the amount of text expected back.
- dofm 2mo agoDo you think the steel birds with the food in will come back if we light torches in long lines on the plateau again?
- trjordan 2mo agoAI is so miserable for this. It's so focused on doing what you ask, it forgets that there's stuff worth doing that you didn't ask for, like defining reasonable abstractions. Getting away from stuff like this is exactly why I want to use AI. When I say "implement this for idle but active users," I _want_it to define isUserActiveIdle() and stuff these 4 conditionals in it. Having to check the generated code for stuff like this undoes, like .... all the benefit of using AI. AI makes all these little decisions for us. I can about some of these decisions. I just want to notice when it's doing this without having to make my eyes bleed reading 10k lines of generated code a day.
- Forgeties79 2mo ago[flagged]
- deleted 2mo ago[deleted]
- francisofascii 2mo agoBefore LLMs we didn't have time for code quality. LLMs make our jobs faster, so now we have time to dedicate to code quality, right?
- javier123454321 2mo agoI argue that is the case in my experience: https://javiergonzalez.io/blog/on-clean-code-2026/ https://javiergonzalez.io/blog/on-clean-code-2026/
- DCKing 2mo agoI run various forms of workflows to run dedicated QA, code review (of various flavors) simplification and text simplification agents. Especially the simplification goes a long way to remove dumb padding, duplication and efficiency. Dedicated docs/comment simplification is also becoming more and more necessary on recent models. For things like feature development in my workflow, the majority of time the agents run and tokens spent is critiquing the code from various perspectives and it's not close. Of course, this doesn't solve the overall issue that agents don't write code like you and still requires a lot of human attention in planning and code review out to clean up leftover issues, and e.g. challenge bad assumptions about architecture and real-world context. A human is still very much needed to cull the slop (or, more gratuitously: align the agent). But IME it does help avoid a lot of pitfalls and makes the code high quality a lot more quickly.
- wxw 2mo agoThe key idea here is that your codebase is context that will be used for future changes. And context determines the model’s output, so it’s still worth having a well-designed codebase. Easier said than done to be honest, especially if there are many people (and their agents) pushing code. It’s hard to keep up these days.
- cmiles74 2mo agoI’m not so sure this matters. My team manages a couple pretty new projects and I still see LLM tools doing this. I’m starting to suspect that vendors are building in these behaviors to ensure the output compiles (never throw an exception, null check every variable no matter what, never change a function or method but copy or inline its code and change that, etc.) I think I would prefer code that is clear, understandable and simple even if it doesn’t compile and needs some straightforward polishing.
- phaser 2mo agoThe first line of my AGENTS.md is: You are an engineer who writes code for *human brains, not machines*. Taken from: https://github.com/zakirullin/cognitive-load/blob/main/README.agents.md https://github.com/zakirullin/cognitive-load/blob/main/READM...
- exabrial 2mo agoWhat I'm seeing is the organizations that had written code standards: * define the software layers, their function, and the max depth allowed * establish a corp code formatter for each language, along with a process to PR it * establish a business vocabulary and what the terms mean * establish a data dictionary, make it part of the database schema/table/col comments Are far more successful with LLMs. You _should_ have been doing this years ago, but with LLMs its a super power.
- esafak 2mo agoJust run weekly cron job to assess code quality and highlight candidates for refactoring. In addition to doing the same in each PR, of course, but things can get through.
- planb 2mo agoI have good results with this prompt after every larger change: Now do a final code check. Is everything tidy and do the components adhere to the principle of separations-of-concerns. Is everything in an understandable and maintainable state? Do we make any assumptions that may not be true anymore? Is any code left over from previous edits or experiments that does not belong into the codebase? Is the documentation still representing the current state of code?
- chopete3 2mo agoThis is a good example of AI native thinking. Teach AI everything and ask it if it has learnt throughly learnt. The results are surprisingly good. I am following similar steps from this article https://www.lucasfcosta.com/blog/backpressure-is-all-you-need https://www.lucasfcosta.com/blog/backpressure-is-all-you-nee...
- cyanydeez 2mo agogood, but this is just a verbose "make no mistakes"; it'd probably make more sense to just setup a nightly cron job that loops through the prior days' work and writes some morning tasks of the same character. The models will interpret this willynilly; but nonetheless, it's often a better than doing nothing.
- weitendorf 2mo agoIt means the same thing to you, but not to the whole spectrum of people using AI. You literally see it on Reddit all the time where people are complaining about the same model either over-engineering or doing too much, vs it being requiring too much steering or not being autonomous or capable enough to hand off tasks to on its own. The reason prompting it to review its own work for loose ends, record any new undocumented or noteworthy behavior, suggest changes to tests/processes to make it go more smoothly the next time, etc is that it’s prescriptive and process-oriented (and thus easily verifiable/done in-context) rather than descriptive and outcome oriented (which to do properly could require way more context than the model has, because it doesn’t know what it doesn’t know about your particular work, only what it’s seen so far). Even promoting it to do these after-the-fact vs as an upfront requirement can have a big impact IMO. If you make “maintainability” part of the task before it’s seen the real work it will focus on general “best practices” crap rather than the real work, so either way if this is something you care about it doing you have to give it guidance for how you want it done. If you were to review the logs of a model after the fact, you’d also not really save on input tokens unless you compressed the context or sharded it out, which can easily miss the small details that constitute the difference between “what actually happened” vs “how the LLM models this general class of problems” unless the first pass involves the entire context anyway. That said I do think there’s a lot of value in building some kind of pipeline for validating and aggregating these “learnings” across sessions.
- k4200 2mo agoI'm not sure this guy is using the same LLMs as we do. A small AGENTS.md or CLAUDE.md easily prevents issues like that.
- Snoopfrogg 2mo agoOr we start writing code without LLMs.
- el_io 2mo agoCat is out of the bag. Other than recreational programming I doubt many will write code without any form of LLM.
- hoppp 2mo agoIf everyone is using LLMs then nobody has advantage In that case, humans with superior skills who can write code become the advantage. That is important for companies that compete with each other.
- footydude 2mo ago> If everyone is using LLMs then nobody has advantage LLMs are a tool like any other - and like any tool there will be people who are better at utilising the tool to achieve an outcome than other users of the tool. Those differences typically come down to a combination of experience, in-depth understanding of your subject/objective and an awareness of the strengths and weaknesses of the tool. TBH the rise of LLMs reminds me a lot of the era when google search emerged. People's ability to utilise a search engine to achieve their aims was massively varied. * Some people were absolutely useless - they struggled to use a search engine to find anything beyond the most basic of things. * Others were ok - they'd be able to dig a little deeper, they knew a few of the tricks of the searching trade and they had a bit of an understanding of where to look/how to look for something obscure. * Some were good - they knew all the key search constraints, they had a good understanding around how data is structured and what keywords and approaches to use when to get to the thing they need * and some had 'google fu' - those people seemed to have a god-like ability to navigate the internet to find the most obscure things in a matter of seconds. LLMs are different to search engines but their rise shares many similarities to them - they are changing the rules of the game in a monumental way; they have fundamentally reduced the barriers to entry in many fields. The skills that made someone valuable in a pre LLM world do still matter, but IMO we're currently starting to go through a major change where the people who learn how to best utilise LLMs within their field will find themselves leapfrogging people with stronger skills who obstinately seek to avoid using the new tools becoming available to them.
- jasonlotito 2mo agolinting tools, static analysis, CPD, etc. These are all old things you can continue to use and are much more robust than anything you can prompt. These should be standard when using LLMs. In fact, you can tighten the rules even more enforcing more restrictions so you ONLY get the output you want. put this behind a pre-commit hook and a CI job that runs on a PR, and it will work wonders. You can have all the prompts you want on top of this, but if you don't have this automated stuff running behind the scenes, you aren't serious about these issues. Looking through some of these comments here, I see lots of people rewriting concrete rules in markdown willing to spend tokens on the hope AI won't miss it where an actual program won't.
- cliglot 2mo ago[flagged]
- godshatter 2mo agoCould someone show me what a shared helper would look like in this case? This code looks easily readable to me and I fear abstracting it will just make it harder to reason about. Is it just variable_with_a_better_name = that conditional?
- simonreiff 2mo agoWhat you want is to guard at the outset of each API call is the same thing -- whether the user is not suspended, active, any other number of things (including more things as you add more functionality), so you want to shift the entire validation logic to its own module. We therefore want to encapsulate the logic of all users being "qualified". I think the best way to realize this is to try to say in as few words as possible what we want. We want the user.toBe.qualified, but we can write that even more efficiently, user.isQualified(), so we can ASK at the top of each API `if !user.isQualified()` and then fail loudly and quickly if so, and then go do something afterwards otherwise. We presumably expect multiple users that will have a property of being qualified, so let's use a class: ```js class User { constructor(data) { this.isAuthenticated = data.isAuthenticated; this.hasActiveLicense = data.hasActiveLicense; \\ many more details... } // Now encapsulate the boolean property of being qualified, for all Users, in one place isQualified() { return (this.isAuthorized && this.hasActiveLicense && this.hasPaidInFull && this.hasAdminPermissions); } } // Now, we can use our isQualified() property at each of our API guard clause by checking if the user is NOT qualified: if (!user.isQualified()) { return res.status(403).json({ "error": "Unauthorized access requested."}); } // Critically, the API guard clause remains identical even if we change the criteria for validation and what it means to be "qualified" ``` There are of course many other ways to solve this problem beyond this approach. For instance, you could export a function called isUserQualified(user) (or more likely userId) then call it somewhat similarly: ```js if (!isUserQualified(user)) { return res.status(403).send("Error: Unauthorized access requested"); } ``` The other approach I like is to use a factory pattern to build a userSession with function arrow notation. That's really helpful when you are getting raw data back from a database call, say as a JSON object. That would look like this: ```js const createUserSession = (userData) => { return { ...userData, // here we use the ...notation for convenience but don't trust this as secure) isQualified() { return ( this.isAuthorized && !this.isSuspended ); } }; }; // Then you instantiate a user session from the request like this: const user = createUserSession(res.session.user); if (!user.isQualified()) { return res.status(403).send("Error: Unauthorized"); } ``` There are actually loads other approaches too, like using class inheritance (define a parent User class and child QualifiedUser class, for instance), or types. I would say that readability here is less a concern than the issue that you have multiple APIs and if you refactor or change the logic for qualified users, now you have to refactor your most sensitive attack surface at multiple points. It's just safer to have that rewrite only happening once, wherever you put it, in my view.
- Black_Triangle 2mo ago[flagged]
- uhhhd 2mo agoCounterpoint: This no longer matters because we are not going back to hand-writing these functions. These patterns were designed to make code easier for humans to read and write, but that is no longer the primary way software is built.
- hollowturtle 2mo agoCounterpoint: as long as context don't rot or it's less effective that starts maintaining repetitions only slightly different. Also > we are not going back to hand-writing these functions do you really think there isn't a good chunk, if not the majority outside some bubbles, of developers that still hand code? Crazy to hear, I bet you're not a programmer
- geraldwhen 2mo agoThe change is exponential and happening daily. The future is smaller teams spending a lot of money on AI credits.
- hollowturtle 2mo agoIf it really is exponential intelligence should have already exploded. Go give away your certainties on a seer's forum
- iecheruo 2mo agoCode structure still matters for cost effectiveness and performance over time https://arxiv.org/abs/2605.20049 https://arxiv.org/abs/2605.20049 https://arxiv.org/abs/2605.13280 https://arxiv.org/abs/2605.13280
- egonschiele 2mo agoIn a similar vein, here's my favorite prompt: "Please review the tests you've written. Will the tests actually test what they're meant to? If the code breaks, will the test fail?" It's amazing how often LLMs will write tests that don't test anything.
- dualvariable 2mo agoI've seen a lot of human-written tests that wind up testing the testing framework and not the actual code.
- djjdfjjddndn 2mo agoyeah but it'll be one or two at a time that you find like that. LLMs will output two dozen tests for one line of real code, where you maybe needed one
- cagz 2mo agoMy workflow is: - Write the test first, confirm it fails - Write the minimum code to make that test pass - Confirm it is green
- t-writescode 2mo agoTDD like this is a very good system for a lot of things, especially brownfield development - gotta make sure you understand the error space before you know you’ve fixed the error. :D
- hollowturtle 2mo agoWe still need to discuss this things for real? Aren't they already taken for granted after all this "experimenting" with LLMs? I'm wondering when we will discuss hand coding again without treating it like a taboo anymore. LLMs can be useful in so many ways it's tiring knowing people are delegating the entire source code typing to agents, to me it's like hearing from people that the web is good and we should be happy with it
- ramshorst 2mo agoSo the new prompt is "Write code like a human will maintain it" ?
- luciana1u 2mo ago[flagged]
- internet101010 2mo agoNo. I will generate code in a way that makes it easier for clankers to maintain it, because they will actually be doing the maintaining. In practice, this means that most of my time is dedicated to improving the repo harness because the state of the repo harness directly determines the quality of the codebase as a whole. At a minimum, there should be precommit checks and CI workflows that cause PRs to fail if the documentation is not up-to-date and synced with the other docs. Then regular codebase analysis for improvement. This is where you find the bug sources, make new modules for consolidation, and get those +5000/-4000 PRs that people stuck in the world of manual code review hate.
- MattyRad 2mo agoThis is an agreeable article, sure, but the idea that an LLM fueled group or team will collectively have this discipline is... idk... bemusing and saddening at the same time.
- rconti 2mo agoI have very mixed results with LLMs, but I actually find they're really GOOD at, unprompted, pointing out existing code that is redundant and could be simplified and so on. Where it really, really struggles for me is in existing complex infra codebases.
- amaze_28 2mo ago[dead]
- imilev 2mo agoWhat happens when shit hits the fan in my exp is that I have to crack open the codebase and debug some portion of it, so I can explain it to myself in order to be able to explain what is wrong to the LLM. Otherwise what I have found is that the LLM will add a new if statement which will handle the newly discovered issue and you start stacking them ifs. As the article mentions LLM's unlike humans aren't lazy, they will copy, paste add patches for every issue, why bother think and understand root cause :d. So as part of our review we have a rule against that as well.
- kccqzy 2mo agoHumans will do this as well, especially inexperienced junior SWEs. Adding a new boolean parameter and some if statements here and there. After a while a seemingly simple function takes four boolean parameters that each control a little bit of what the function does. The benefit is that a human who is a junior might need at least a few weeks to months of guidance to have a good taste of when to duplicate and when to DRY. An LLM likely already has good judgment, and your prompt merely needs to be activate this judgment.
- baptou12 2mo agoI agree, but “write code like a human will maintain it” can also be limiting: if LLMs reduce the cost of maintaining more explicit or verbose code, we should use that to raise the standard, not preserve compromises made for human convenience.
- bluGill 2mo agoWill it? Okay, first we need to ask "which humans" - there are many humans who don't see a point in the things we call best practices. I've work with programmers who are faster than me to getting low bug count code out the door, despite writing 70,000 line functions - he didn't understand why nobody else wanted to add new features to his code. The standards most "good developer" humans demand were learned from many decades of painful experience about what happens when you do it the other way. These are not only compromises for human convenience, they often are things that we have learned will come back to bite you later even though they just add more work today for no gain.
- WillAdams 2mo agoHowever, an argument can be made that such Literate Programming code can be easier/better for an LLM to work with: https://news.ycombinator.com/item?id=47300747 https://news.ycombinator.com/item?id=47300747
- sheept 2mo agoAren't LLMs trained on and optimized for human code? In general, anything that is concise is more effective as context for the LLM, whether it be your CLAUDE.md or code, since LLMs are meant to model human language.
- baptou12 2mo agoHumans can share context outside the code, while LLMs need it to be more explicitly structured inside. And if we keep the slightly verbose good practices that already help humans understand the intent, we kind of get the best of both worlds.
- alexsmirnov 2mo agoThe problem of duplicated code described in the article, goes in a different way in reality: AI does not update 4 places in the same way, but implement them a slightly different. I found diverged business logic all the time. For example, file upload dialog for a document with the same meaning: in one place, it accepts pdf only. Another allows to upload pdf or docx. The last accepts pdf, doc, docx, and txt.
- snarfy 2mo ago## HARD RULE - design scope must always be maintained and no function should ever be longer than XXX lines and no class should have more than Y methods. Create new classes and subclasses and refactor until the criteria are met. You'd be surprised how readable this makes the code when XXX is about the size of your vertical screen and Y is relatively small.
- twelve40 2mo agobut then you end up with a clusterfuck of classes?
- t-writescode 2mo agoYou’d be surprised how often this doesn’t end up happening, especially in languages that are supportive of this style: Kotlin, Python and Typescript, to name a few. A lot of functions you write are helper functions, wrapper functions, system functions, etc and all 3 languages support making things modules of interconnected concepts, extension functions, etc. You can make code very readable this way - arguably more readable. Have you ever had so many tests for a single class that you’ve broken the test class into a package and have a whole file / test class for each big method? Same idea! :)
- t-writescode 2mo agoSimilarly, I try to follow an “around 400 lines per MR” (violations can exist for test code if something is particularly gnarly). I’ll build whole features and then break them apart into several MRs that chain off each other. Everyone who has seen this style has been really grateful for it and finds my code much more readable. I encourage and embody the pattern everywhere I go. Exception: For mass find/replace or auto-linter changes, that’s all one MR, and is usually pair programmed so the other person can confirm that’s all I did, still easing cognitive load.
- jaredcwhite 2mo agoWrite code like an agent will never touch it, that's my motto. (Because it's true.)
- illuminator83 2mo agoI've seen lots of code that people have maintained for 20 years and its full of these duplication and worse. In fact I'm sad to say that majority of code I've seen people write and maintain is worse than what LLMs produce today. Often it is inexperience, sometimes it is willful negligence, but most often it is just tight deadlines and pressure to do finish whatever is being done right now. People know how to do it better, but nobody got the time and budget to actually do it. LLMs also learned from that.
- axpy906 2mo agoThis. Before LLMs there was copilot which repeated a lot. Then before that we had copy paste and stack overflow.
- hakunin 2mo agoI have been on a quest to get AI to code like me, using pi harness, and any model that it can support. I'm mostly a Ruby programmer, so here's my journey so far. 1. Created a "coding" skill with every practice I posted on my blog website, as well as a bunch I had in the queue to blog about but never got a chance, summarized into "do this" kind of language. This is more or less good for any PL, but a bit Ruby-slanted. 2. Created a "rails" skill because that's my framework, where similarly I explained my approach to architecting Rails apps. 3. Created a "writing" skill where I literally fed it my entire blog, and tried to get it to write more like me (mixed success, weaker models did better for some reason, but I haven't tried the GPT-5.6 series yet). 4. Next, I really wanted it to format code exactly like I would, even things like "let's make this `if` into a ternary, let's split these assignment groups with a line break, let's vertically align here, but not there", but with GPT-5.5 (my primary driver up until yesterday) there's almost no way to make a skill of reasonable size that will be consistently applied. So instead I instructed the agent to write me a Rubocop cop for every single situation I ever encounter where I would've formatted code slightly differently. This was quite powerful, because I usually thought of linters as enforcers of objective consistency decisions in the codebase, but this was me going full format nazi on the agent. And the nice part is that these cops can contain some non-autocorrectable feedback, which AI will follow. 5. I'm working on a review loop where the most easily missed parts above get double checked. This is the first thing I'm doing with pi subagents. (I feel like I'm getting better results if I don't use subagents for code exploration, other tool calls). The idea here is that I want reviews to be in the implementation loop. I always read/review code in the end, but so want it to have gone through the review loop before it gets to me. Since implementation is already context-heavy, I want to be able to orchestrate this loop without adding to the implementation context. 6. I'm also adjusting all of the above for GPT-5.6, because it requires less guidance, so I'm carefully trimming the verbiage to save tokens. So far the results have been surprisingly good. I want to experiment with GLM-5.2 running under these constraints. One invariant in all of this: I read the code. My end product is not working software, it's good code (which also incidentally produces working software).
- dionian 2mo agomy LLM does this pretty well with my coaching. i use a good model and i encourage it to make such improvements. and since the llm is trained on human maintainers it works fine.
- __MatrixMan__ 2mo ago> Who cares about DRY? You don't have to be the one updating the same long conditional in four different files - the AI will just do it for you! Right? One pattern I've really been enjoying lately has to do with a language called haxe. It's designed to be compiled into other languages (java, python, others). There's this extension called reflaxe which lets you make mini compilers for compiling haxe into pretty much anything. So if I have anything with duplicate structure... like maybe I want the CLI subcommands to resemble the http API. $ foo bar --baz 6 # produces similar output as HTTP GET /foo/bar?baz=6 ...and `docs/generated/foo.md#bar` should have documents both the CLI and the http usage. Then I have the LLM maintain a haxe source of truth and then have it compile that source of truth to the other stuff. Previously I was using OpenAPI spec's and generators for this, but they wound up feeling like a black box that I ended up debugging all the time. The reflaxe setup is much more generic. So you end up with this mountain of generated code, but unlike LLM-generated code it's obviously generated (in .../generated/thingy.py or whatever) and a comment at the top of the file says where to look to learn how it's generated). I'm generating docs this way, accessor functions for database tables and SQL for making those tables, matching clients and servers in different languages... it replaces a lot of purpose built tools with just one, and LLMs are pretty good at it. So even though the repo is large, the parts of it that are authoritative remain small. I find LLM's manage this boundary much better because it's so crisp an in their face. But they have to be told to do this, otherwise they'll just create context-size problems that they'll later struggle with. Of course you could do this with yaml files or some such, but unlike yaml, haxe has a type system, you can write tests in it, so the agent can notice fundamental flaws before the generation happens... with yaml those flaws would be propagated into the generated code before they'd get noticed.
- vorticalbox 2mo ago> There's a much cleaner way to do this - a shared helper disagree, then you end up with something this this function checkAll(target, conditions) { return Object.entries(conditions).every(([path, expected]) => { const value = path.split('.').reduce((o, k) => o?.[k], target); return typeof expected === 'function' ? expected(value, target) : value === expected; }); } and const ok = checkAll({ user, account }, { 'user.isActive': true, 'user.isSuspended': false, 'account.status': 'open', 'user': u => u.hasPermission('read'), // predicate for the trickier bit }); how is that better?
- yCombLinks 2mo agoNo, you've created a generic condition checker, which is where all of your complexity comes from. Further, you've left the actual check to be duped in all callers.
- vorticalbox 2mo ago[dead]
- fgeytk2 2mo ago[dead]
- metalspot 2mo agocode review is a dead end. the only way building with AI makes sense is in secure systems that can run unaudited code. code review has always been a liability fig leaf. it is much harder to understand a system from reading the code than writing the code. if AI can write code 100X faster than humans it is simply impossible for humans to do real code review. effectively it is just pretending to do code review, and then running unaudited code without the proper systemic security guardrails in place.
- dualvariable 2mo agoI think the usable counterpoint here is that you can refrain from excessively DRY'ing code up and defer it until later. There's a huge cost to Clean-Code-style DRY'ing of your codebase which is that you wind up creating all kinds of little functions that all add cognitive overhead to reading your codebase, and that premature DRY'ing can lead to picking the wrong abstractions. If you can tolerate a bunch of copypasta, you can sit back after you've written 5,000 or 10,000 lines of code and can look at the actual result, instead of speculating, and make better-informed decisions about how to clean the codebase up. If you're making those decisions the first time you copy a bit of code around, you can wind up making a worse mess, since you often don't know where you're going.
- clintonb 2mo agoMy threshold is three. The third time I duplicate code/behavior is when I start to think about DRYing said code/behavior.
- 383toast 2mo agothis article according to pangram was AI generated, ironic
- jwpapi 2mo agoCrazy how many engineers in here just say they are using another prompt on top. From my experience that makes things worse. It does abstractions, but the wrong ones. It overcomments, confusing future calls of the LLM. To me building on multiple scalable systems this has been the most dangerous part of LLMs. On a good codebase it will work good, but it will maek it worse, so you keep using it, till it doesnt work and then you have to pay the bill and fix for what you didn’t build before. If you put an agent on a fresh codebase 2 things are often given: -> You have a mental model of the code -> The code is somewhet concise After multiple iterations both is lost and LLM performance degrades. To solve this you can regular refactor, but it’s not a nice experienc. So my best solution is: I use LLMs for exploration and for review, but I write the code myself. I find it hard to believe why so many engineers try to avoid it. It’s not consuming much of my time. And it’s actually the most enjoyable part. Sometimes I race AI i give it a prompt /bug to fix and at the sametime im greping/symboling through the codebase and tryto fix it myself. AI isn’t always faster.
- M0r13n 2mo agoExactly. I follow a similar workflow. I am still writing code by hand. Not all code. Parts are generated by Opus.
- radlad 2mo ago> I use LLMs for exploration and for review, but I write the code myself. I find it hard to believe why so many engineers try to avoid it. It’s not consuming much of my time. And it’s actually the most enjoyable part. At my workplace, there is more work to be done than there is engineers, and approximately 2 engineers per service. I can spin off multiple Claude Code instances on unrelated work, steering them occasionally, and then finally reviewing the output. After I have reviewed it, I post it for team review. You're absolutely right that my depth of familiarity is lesser with this code, but we are absolutely shipping more as a result of increased parallelization. The bottleneck now is typically reviews - both pre-push and team reviews.
- M0r13n 2mo agoThis seems to assume more code shipped equals more work done. I am still not convinced that this is necessarily the case. Sometimes it is. Sometimes it is not. You mentioned that reviews are now the bottleneck and that your familiarity with the code has decreased. That tradeoff might eat into the parallelization gains over time.
- praveer13 2mo agoFor writing for human consumption, I’ve taken to hand writing the docs and having agents review and suggest improvements.
- lowbloodsugar 2mo agoSOLID is a good idea that most coders I know don’t follow because they can’t be arsed. Turns out AI is really good at writing SOLID code (if you tell it to) and SOLID code is much easier for AI to reason about.
- RALaBarge 2mo agoI think the biggest conceit here is the expectation that humans will continue to do this task in the medium to long term. This was good advice in the past but when inference is ubiquitous and most code ends up being Claudewritten anyways, there is little point. If you are writing C for NASA/ESA then yes of course. For the 99% of the rest of us, probably not so much in the coming years.
- davnicwil 2mo ago> The next time you ask the LLM for another endpoint with the same access rules, the model won't start from first principles. It'll start from the other four copies already sitting in your repo. To be honest I'm not sure how true this is. I think it's more that there does seem to be quite a baked-in bias to repeat basic structures and not reuse (much less come up with) abstractions. So where that is the existing pattern it looks like it's keeping with that, when in reality it would often do that either way. There have been many cases where I've started a piece of work by laying down very rigid abstractions and a few examples of using them, and I explicitly prompt to not only exclusively use the specific abstraction API but also copy the way I've used it. And the (frontier) LLM does neither, it just steams ahead re-implementing things from scratch from bottom up basic structures, partially and often totally ignoring the abstractions. I don't know exactly why this should be the case but my naive suspicion is that there's just an awful lot of this type of stuff in the masses of training code and the weights just somehow 'know better' how to get results this way, rather than using your more novel abstractions/patterns.
- stingraycharles 2mo ago“ There have been many cases where I've started a piece of work by laying down very rigid abstractions and a few examples of using them, and I explicitly prompt to not only exclusively use the specific abstraction API but also copy the way I've used it. And the (frontier) LLM does neither, it just steams ahead re-implementing things from scratch from bottom up basic structures” Yup, this is the sad state of affairs that we’re currently in, and the only way to avoid this is to specifically instruct the model on how exactly to implement things. From my point of view, I think this is fine, to be able to use these LLMs as fast implementation engines. The challenge is to make it surface these types of implementation decisions before it goes off doing it the wrong way.
- MariusGjerd 2mo agoStart asking your peers to explain what their code does and alot will be surprised that they dont know
- willtemperley 2mo agoYawn. So people are discovering SWE hasn’t actually changed in its basic principles. Is this going to be the new “how I use LLMs” article? Good night
- acedTrex 2mo agoThe fact this is controversial is wild and a grim sign for an already struggling industry.
- jtr1 2mo agoMost programming best practices were created to solve for the same problem LLMs face: limited context. The principles around well-crafted code strove to make it modifiable by future agents who are not the author. Maintainable code stabilizes around the invariants of the domain it address while providing a spectrum of modifiability to future users, running from UI > configs > cleanly abstracted code > core.
- steilpass 2mo agoCoding Agents are the best reason to write Clean Code (TM)
- deleted 2mo ago[deleted]
- andai 2mo agoIt might just be me, but AI has made my code more human-maintainable. They've been complaining about obsolete comments, separation of concerns, testability, global mutable state... (Also performance and security issues, addressing which doesn't make the code more readable, but does make the program itself more robust.) That being said... I have found them weirdly unsuitable for some tasks though, e.g. asking frontier LLMs to assist me with game development, I found that they were not able to add simple features to a simple Pong clone (nor even port a working Pong implementation) without constantly breaking things. (Yes, Pong, from 1972!) So, I want to say YMMV, but just the past 2 weeks, my own mileage has varied very much! They seem to be extremely domain specific. "Half the time, it works every time!"
- koinedad 2mo agoMaybe we should start writing code like the LLM will maintain it. I’d be curious if there are weird optimizations that the LLM can drive that might not be things that help us humans like DRY etc. Edit: this small things drive me crazy when I’m coding with LLM… which is basically all the time these days, but I also read all the code as well.
- addybojangles 2mo agoGood advice, in this age of just moving forward and onward, having the common courtesty here will not only save yourself, but also anyone else that needs to wade through everything.... Write code like a coworker you really like will maintain it.
- Savageman 2mo agoI have a meta review command, instructions is more or less: - run the commands /code-review and /simplify in finding mode (read-only, no fix) - run another review command internal to my company Collect all findings and classify into Blocker/Maybe/Nits. Very simple, but effective: I like it very much!
- holoduke 2mo agoFor every feature prompt I do I have about 2 or 3 maintainance prompts. For example. Check code for smells and dead code. Check modularity of our application logic. Check for possible performance issues. Check for optimizations. Etc etc.
- axpy906 2mo agoWonder what LLM op is using? I find that using one LLM to review the other catches a lot of this. For example having Codex do the work then CC /simplify and /code-review. Claude md has three lines one of which is DRY. You still have to look at the diffs because it won’t have external knowledge to the codebase or make the best decisions. It does find bugs and keep things simple.
- aioproductos 2mo ago[flagged]
- agentultra 2mo agoWild idea: just write code. I know. It’s an unbelievable concept in this AI era. Write code? Isn’t that what dinosaurs did? If you expect that a human will need to read and maintain that code you might as well write it for them. You’ll get annoyed by having to read overly-verbose copy-pasted code. So will they. So write the code yourself and bringo: you’ll fix things yourself and write things in a way that makes sense for other humans to maintain. Or you can come up with a convoluted web of markdown files to try and coax your agents and loops to understand what future human maintainers will expect the code to look like. I’m not sure what path will be easier in the long run. Anyone inherit a loop-based agent-driven code base yet and have to try to understand it?
- bodash 2mo agoIt’s not crazy. I always add a simple message to my prompts: “leave 20% solutions empty and I’ll implement them myself”. It work wonders for me.
- tzone 2mo agoI think people have outdated ideas on AI code quality. Latest ones (i.e. ones after Claude Opus 4.8) are a game changer. They now write better code than a lot of engineers. They are also able to understand much larger overall context and make less mistakes then most engineers would make. Difference between something like Opus 4.8 and even 4.5 is massive, not even talking about difference between Opus 4.8 and Sonnet or Composer. What i see online is that a lot of people are using cheaper models, stuff like sonnet or cursor composer or even latest cursor grok. But they aren't the same thing as using the best models. The difference in quality and correctness is huge.
- agentultra 2mo agoI always have to ask people, correct with respect to what? The reason being that most software developers aren’t very good at specifying systems precisely enough that they can confidently determine whether their program does what they think it does. We don’t need to specify systems to the rigour of mathematical proofs every time, of course. The point is that spoken language isn’t precise enough to measure correctness against. When you suggest that the difference in correctness is huge, I can’t really understand what you mean. Correct with respect to how you think good software should be written? Correct with respect to informal specifications written in prose? How? I know that the frontier models have large contexts and can compress a lot more tokens from their training sets. But how does that make it able to read your mind and make formal what is ambiguous or informal?
- dexterlagan 2mo agoWild(er) idea: expect future AI to maintain current AI-written code.
- kordlessagain 2mo ago"Hey Sol, write this like your kids will maintain it, because I'm the sure hell not"
- Ancapistani 2mo agoI disagree. The general intent is fine, and I'm certainly not abandoning everything we've learned as an industry - but LLMs are not people, people are not LLMs, and there's no reason to believe that the coding practices we've found to be good for humans will be good for LLMs. Each time we apply a practice like this, we should ask ourselves what problem it was intended to solve, whether that problem still exists for LLMs, and if the existing practice is the best fit for LLMs.
- chickensong 2mo agoThe article is conflating LLM usage with bad habits. When you start a project not everything is DRY, and you don't start pulling out shared helpers until they're called for. If you're a slacker and expect the agent to magically fix everything with one-off prompting and only moving forward, it's not going to work. Agents prefer to carry existing patterns forward, just like many humans. The shared helper example from the article requires intent to refactor. If you ask the agent look for smells and refactor, it will happily assist you with that. If you ask it to add a feature, which happens to add duplication, you get a feature with duplication because you didn't specify anything else. Better yet, add tooling like static code analyzers (shout out to Credo) to your development pipeline and catch stuff like this regardless of LLM. Verify against a mechanical baseline, with LLM judgement layered on top as-needed. "The most frustrating part: I thought I was outsourcing maintenance to the LLM, but the slippery slope I found myself on was actually training it to have ever-worsening habits." That's on you. The LLM is a tool and you're not using it well. Build a good foundation for the agents to anchor on, and you'll get good results moving forward.
- tangenter 2mo agoThe fact that people have to resort to hacks and tricks to do basic coding tells me that the quality of code generated by these frontier models is mediocre at best. And I’ve had the same happen - the code, the comments, is at the level of a junior developer. AGI my ass.
- t-writescode 2mo agoI have been impressed with them as a “on this line” or “the next couple lines” autocomplete, though. My first real use with them as that was during an interview with Jetbrains’ assistant enabled and I repeatedly went “oh! Huh!”, so … in that form, it seems very good but that’s first impressions and everything feels like magic at first
- wpollock 2mo agoThe title of this post reminds me of a favorite quote "Write code as if the next person to maintain it is a homicidal maniac who knows where you live!"
- joshka 2mo agoI wonder how effective it would be to just put the blog's title as a line in your AGENTS.md... This is kinda the "this could have been an email" of AI complaints. As an AI acolyte, I strongly believe that AIs should be being trained for this sort of mode by default, but they tend to be optimized (or at least tested) to solve the single shot benchmarks rather than multi-step stuff that you really need in a long term maintainable project. There is a https://www.scbench.ai/ https://www.scbench.ai/ SlopCodeBench that checks this and a variety of others. These don't seem to often come up when frontier labs are advertising their new models.
- ritcgab 2mo agoHeat death is inevitable in a codebase built mostly by coding agents.