Write code like a human will maintain it
Write code like a human will maintain it: learn why maintainability beats clever shortcuts and how AI copilots amplify your best and worst coding habits.

The single most consequential decision you make when writing code is not which framework to choose or which algorithm to use — it is whether the next developer who reads your code will understand it in thirty seconds or thirty minutes. That principle has always mattered; in the era of AI-assisted development, it has become existential.
The phrase "write code like a human will maintain it" sounds almost redundant, yet every codebase in production is quietly drifting toward chaos because developers — aided and abetted by large language models — are accepting shortcuts they once would have rejected on sight. This article makes the case for why maintainability is the highest form of technical craft, and exactly how to achieve it with or without an AI copilot in the loop.
The Psychopath in the Room: A Classic Quote That Hits Harder Than Ever
Long before ChatGPT, developers had a colorfully brutal way of framing the maintainability imperative. In September 1991, John F. Woods posted the following to the comp.lang.c++ newsgroup — a quote that has since been immortalized across Stack Overflow, Reddit, the c2wiki "Code For The Maintainer" page, and countless engineering blogs:
"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
— John F. Woods, comp.lang.c++ newsgroup, September 1991
Jeff Atwood of Coding Horror brought the quote to a wider audience by surfacing it from the c2wiki "Code For The Maintainer" page, noting that maintenance programming — fixing, extending, and refactoring existing code — is where most real-world software work actually happens. The greenfield excitement gets the blog posts, but the unglamorous work of keeping systems running is what consumes developer time. When you write code as if someone hostile will inherit it, you are really practicing radical clarity: naming things well, keeping functions small, avoiding tricky cleverness, and leaving a trail of context that makes intent obvious.
The phrase "write code like a psychopath will maintain it" is not really about fear. It is about understanding the asymmetry between the cost of writing clean code now (slightly higher upfront) versus the cost of maintaining cryptic code (exponentially higher, forever). Today that asymmetry is amplified because the "maintainer" might not be a human at all — it might be an LLM that will read your existing patterns and reproduce them verbatim across dozens of new files.
The New Danger: How LLMs Learn Your Bad Habits
The most important insight from the Unstack analysis of AI-assisted development is not about AI capabilities — it is about AI behavior as a mirror. LLMs used for coding are, in a very practical sense, pattern sponges. They absorb the structure, style, and shortcuts visible in your open files, recent commits, and surrounding context. They do not start from first principles; they start from your principles — whatever those happen to be.
This creates a dangerous feedback loop that plays out in four distinct stages:
- A shortcut gets merged. A developer, pressed for time, accepts an AI suggestion that duplicates logic rather than extracting a shared helper.
- The shortcut becomes the pattern. The LLM reads the existing codebase on the next prompt and treats duplication as the house style.
- New code compounds the problem. Future AI-generated code reproduces the bad pattern, spreading it further across the repository.
- Manual intervention becomes unavoidable. Eventually no prompt can fix the structural issues; a human must wade in, understand months of accumulated chaos, and refactor by hand.
The Unstack analysis uses a concrete, instantly recognizable example. An access-control guard like:
if (user.isActive && user.hasPermission('read') && !user.isSuspended && account.status === 'open')
gets copy-pasted into a route handler, a background job, an API endpoint, and a webhook — because the AI saw it done once and repeated it. The correct solution is a single shared helper function. But once the duplication exists, every subsequent AI suggestion reinforces it. The model has effectively been trained into worse habits by the codebase it is assisting with.
The implication is stark: the discipline of writing maintainable code is no longer just about the next human developer — it is about keeping your AI copilot from dragging your entire codebase into entropy. This is why the foundational principle — write code like a human will maintain it — has acquired new urgency in the age of AI-assisted development.
What the Data Says About AI Code Quality Today
If you suspect that AI-generated code has a measurable quality deficit, the research backs you up. A December 2025 study by CodeRabbit analyzed 470 open-source GitHub pull requests — 320 AI-co-authored and 150 human-only — and found that AI-generated PRs contained approximately 1.7 times more issues overall (10.83 issues per PR versus 6.45 for human-only PRs). The gap is consistent across issue types, with particularly alarming divergence in readability and performance categories.
| Issue Category | AI vs. Human Rate | Impact on Maintainability |
|---|---|---|
| Logic & correctness errors | 75% more common in AI code | High — requires debugging and test coverage |
| Readability problems | 3× more common in AI code | Critical — directly blocks future maintenance |
| Error handling / exception gaps | ~2× more common in AI code | High — causes runtime surprises in production |
| Security vulnerabilities | Up to 2.74× more common in AI code | Critical — exposes systems to attack vectors |
| Formatting inconsistencies | 2.66× more common in AI code | Medium — causes cognitive load during review |
| Naming inconsistencies | ~2× more common in AI code | Medium — obscures intent across codebase |
| Excessive I/O operations (performance) | ~8× more common in AI code* | Critical — causes user-facing slowdowns at scale |
*Note: Performance issues were rare in absolute number, but the subset involving excessive I/O operations was skewed heavily toward AI-authored PRs — making the 8× ratio a signal worth taking seriously even if individual occurrence counts remain low.
Critically, the study notes that AI and humans make the same types of mistakes — but AI makes them more frequently and at far larger scale. The readability figure is especially striking: AI code is three times more likely to have readability issues than human-written code, which maps directly onto the maintainability problem you will face six months after deployment. You cannot maintain what you cannot read, and you cannot debug what you cannot understand at a glance.
The I/O performance data (8× more common) is particularly instructive. It reveals that AI models frequently optimize for syntactic correctness and immediate functionality while remaining blind to the cumulative cost of repeated allocations, inefficient loops, or unnecessary database queries. A single N+1 query that an experienced developer would spot in code review can multiply across dozens of AI-generated endpoints, each appearing functionally correct in isolation but collectively degrading system performance at production scale.
Writing code is like writing prose: fluency and correctness are not the same thing. An AI can produce syntactically valid, functionally adequate code in seconds — but syntactically valid and actually readable are very different bars to clear.
Can ChatGPT Write Code Like Claude? Comparing AI Models for Maintainable Output
One of the most searched questions among developers right now is whether different AI models produce meaningfully different code quality — and specifically, whether ChatGPT can write code like Claude when it comes to production-grade, maintainable output. The answer has direct implications for teams deciding which AI tools to standardize on.
Based on current benchmarks and developer experience data, the short answer is: both can produce production-ready code, but they have different defaults and performance curves. According to Rapidevelopers' November 2025 comparison, with the caveat that model versions and benchmarks evolve rapidly:
- Claude Sonnet 4.5 (Anthropic) leads on SWE-bench Verified with a 77.2% pass rate (rising to 82% with parallel compute), compared to GPT-5's 74.5% and GPT-5 Codex's 72.8%. Claude tends to produce more production-ready code from the first attempt — automatically incorporating documentation, consistent formatting, and structural design considerations. It handles larger codebases more coherently thanks to its 200,000-token context window (expandable to 1 million tokens for enterprise users). Professional tools like Cursor IDE default to Claude for this reason, and teams report fewer rounds of revision when using Claude for multi-file refactoring or architecture-level changes.
- ChatGPT / GPT-5 (OpenAI) generates functional code quickly and excels at rapid prototyping, conversational debugging, and multimodal tasks. GPT-5 launched with a 400,000-token context window — a significant leap from GPT-4o's 128K — making it more capable than earlier generations for large codebase work. However, it can be less consistent over long sessions and is more prone to formatting drift in extended conversations. Note that available context window sizes vary by subscription tier and may change as OpenAI updates its product offerings.
The practical takeaway for teams is not "pick one and trust it" — it is that no model reliably produces maintainable code without deliberate human oversight. Both Claude and ChatGPT can hallucinate non-existent APIs, suggest deprecated libraries, and reproduce your codebase's bad patterns just as readily as they reproduce good ones. The model choice shapes your starting point; your review standards, linting rules, and code style enforcement determine the finish line.
For teams prioritizing maintainability over iteration speed, Claude's larger context window and more consistent output make it the pragmatic choice for complex, multi-file projects. For rapid prototyping or single-file tasks where style consistency is less critical, GPT-5 remains highly capable. Neither model should be used as a substitute for code review; both should be paired with comprehensive linting, formatting automation, and human review gates before any code reaches main.
How to Write Code Like a Professional: Seven Concrete Principles
Whether you write code entirely by hand, co-pilot with an AI, or review AI-generated output, the following principles are the foundation of maintainability. These are not stylistic opinions — they are the mechanisms by which code survives contact with the real world over months and years.
1. Name Things for the Reader, Not the Machine
Variable and function names are the primary documentation layer of any codebase. A name like d or temp2 forces every future reader to re-derive its meaning from context. A name like daysSinceLastLogin or calculateAccessControlStatus(user, account) is self-documenting. The rule of thumb: if a name requires a comment to explain it, the name is wrong. When you write code like a professional, you treat naming as a first-class design decision, not an afterthought. This principle is especially critical with AI-assisted development, because LLMs frequently default to generic names (data, result, process) when the surrounding code does not provide enough context to infer more specific intent.
2. The DRY Principle Is Not Optional
Don't Repeat Yourself (DRY) is the direct antidote to the copy-paste anti-pattern that AI tools amplify. Every time logic is duplicated, you create multiple future bug surfaces and multiple update points. Extract shared logic into clearly named helper functions, utility modules, or service layers. The access-control example above — that cascading boolean check duplicated across four locations — is precisely the kind of smell that makes a codebase unmaintainable within months. The additional burden with AI assistance is that duplication, once present, becomes the implicit standard: the model will continue replicating it across new functions and endpoints unless you actively refactor it out and commit the cleaner version back to the codebase.
3. Write Short Functions That Do One Thing
A function that does three things is a function that is impossible to test, impossible to name accurately, and impossible to reuse. The single-responsibility principle applies at every level: functions should do one thing; modules should own one domain; classes should represent one concept. If you struggle to write a one-line description of what a function does without using the word "and," it needs to be split. This discipline is especially important when reviewing AI-generated code, which frequently bundles orthogonal concerns into single functions to minimize line count.
4. Comments Explain Why, Not What
Novice developers under-comment; intermediate developers over-comment the obvious; experienced developers comment intent and rationale. A comment that says // increment counter above i++ is noise. A comment that says // We use a 30-second retry window here because the upstream API rate-limits at 2 req/min, and short retries would hammer their quotas is invaluable context that will save the next engineer hours of archaeology. Use comments sparingly, and when you do, make them earn their place. The "why" is what does not appear in the code itself; the "what" is self-evident to anyone who understands the language.
5. Avoid Magic Numbers and Hard-Coded Values
The number 86400 embedded in a calculation means nothing without context. The constant SECONDS_PER_DAY = 86400 defined at the module level is self-explanatory and trivially refactorable. Hard-coded strings and numbers are one of the most common ways that AI-generated code fails the readability bar — models frequently inline literals that a professional developer would immediately extract into a named constant or configuration value. This is particularly dangerous in domains like payment processing, rate-limiting, or security thresholds, where magic numbers can hide assumptions that future maintainers (or auditors) need to understand.
6. Keep Consistent Style — Especially in Teams
Consistency is not about aesthetic preference; it is about cognitive load. A codebase where some files use camelCase, others use snake_case, some use 2-space indentation, and others use 4-space indentation forces every reader to context-switch constantly. Adopt and enforce a style guide — for Python, that is PEP 8; for JavaScript, it is ESLint plus a chosen preset; for Java, it is Google or Spring style conventions. Automate enforcement with linters and formatters so that neither humans nor AI can introduce inconsistencies silently. The CodeRabbit study found that formatting inconsistencies are 2.66× more common in AI code, which suggests that LLMs are particularly susceptible to drifting style when different sections of a codebase have different conventions.
7. Structure Code to Communicate Intent
The highest level of maintainable code is code that communicates architectural intent through its structure: directory layout, module boundaries, abstraction layers, and the names of the things that hold other things. When a new developer (or a new AI session) opens your repository, the structure itself should tell a story. That means deliberate layering, clear separation of concerns, and a README or architecture document that explains not just what the system does but why it is organized the way it is. Clear architecture becomes the guardrail that prevents AI-generated code from violating domain boundaries or introducing inappropriate coupling between layers.
Writing Pythonic Code Like a Seasoned Developer
Python deserves a special mention because it is simultaneously one of the most readable languages ever designed and one of the most frequently abused by developers who write Java or C with Python syntax. The concept of Pythonic code — idiomatic, leveraging the language's own idioms rather than transplanting patterns from other languages — is the Python community's answer to the maintainability problem.
Michael Kennedy's Talk Python course Write Pythonic Code Like a Seasoned Developer covers more than 50 concrete tips across nine topic domains — Foundational Concepts, Dictionaries, Generators and Collections, Methods and Functions, Modules and Packages, Classes and Objects, Loops, Tuples, and Python for Humans. The most impactful habits include:
- List comprehensions and generator expressions instead of verbose
forloops with repeatedappend()calls — not just for conciseness, but because the comprehension syntax signals to readers that you are constructing a collection, not performing stateful iteration - Properties (using the
@propertydecorator) instead of Java-stylegetX()/setX()methods, which are un-Pythonic and add visual clutter without adding functionality - Leveraging the standard library (
collections,itertools,contextlib,functools) rather than reinventing what already exists — not just for code reuse, but because every Python developer recognizesdefaultdictat a glance, whereas a custom-rolled version requires reading - Using slices cleanly (e.g.,
items[1:-1]) instead of manual index arithmetic, which is both more readable and less error-prone - Generator-based patterns for memory efficiency at scale, using
yieldto avoid materializing entire lists in memory - Adhering to PEP 8 — not as a style preference but as a shared professional contract that every Python developer expects to encounter
- Context managers (using
withstatements) for resource management instead of manual try/finally blocks, which is both safer and more readable
The reason Pythonic code is specifically more maintainable is that every experienced Python developer immediately recognizes idiomatic patterns. Non-Pythonic code forces readers to decode the author's intent at the language level before they can even begin to reason about the business logic. That cognitive tax compounds with every file they open.
AI models trained heavily on Python can produce Pythonic-looking code — but they frequently backslide into verbose, non-idiomatic patterns when the surrounding code they are reading from is itself non-idiomatic. This is the mirror effect again: the quality of the AI's output is constrained by the quality of the context it is given. A codebase full of verbose for-loops and manual type-checking will train your AI copilot to reproduce those same anti-patterns.
Key Takeaways: Maintainability in the Age of AI
- Maintainability is not a bonus feature — it is the primary obligation of every developer, because maintenance is where the overwhelming majority of software work actually happens. The CodeRabbit study confirms that the cost of poor maintainability is measured in additional bugs, security vulnerabilities, and performance regressions, not just slow onboarding.
- The "psychopath maintainer" heuristic, coined by John F. Woods in a comp.lang.c++ newsgroup post in September 1991, remains the most memorable framing: write code so clear that even a hostile, irrational reader cannot misuse or misunderstand it. This principle has only gained urgency now that the "reader" might be an LLM reproducing your patterns at scale.
- LLMs amplify your codebase's patterns — good and bad. Merging one shortcut today teaches your AI copilot to reproduce that shortcut across dozens of new functions tomorrow. This feedback loop means that code quality discipline is now a prerequisite for safe AI-assisted development, not a luxury.
- AI-generated code carries measurably higher defect rates: 1.7× more issues per PR, 3× more readability problems, and ~8× more excessive I/O operations than human-authored code, per CodeRabbit's December 2025 analysis. The I/O regression concentration is particularly alarming for teams scaling to production traffic.
- Claude Sonnet 4.5 currently leads SWE-bench Verified with a 77.2% pass rate, outperforming GPT-5 (74.5%) and GPT-5 Codex (72.8%) for production-grade, maintainable code in complex, multi-file projects — but no model is a substitute for deliberate human code review and automated quality gates. These figures will shift as both Anthropic and OpenAI release new versions.
- The seven principles — meaningful names, DRY logic, single-responsibility functions, intent-driven comments, no magic numbers, consistent style, and structure-as-communication — apply equally to hand-written and AI-assisted code. They are the guard rails that prevent codebases from drifting into unmaintainability.
- Writing Pythonic code like a seasoned developer is a concrete, learnable discipline that makes code recognizable, efficient, and maintainable for every Python developer who follows you. The same principle applies to every language: know the idioms, use them consistently, and refuse to let AI (or human colleagues) introduce non-idiomatic patterns into the main branch.
What Comes Next: Maintainability as a First-Class Metric
The industry is slowly catching up to the reality that shipping AI-generated code fast and shipping maintainable code are not the same goal. Tools like CodeRabbit, SonarQube, and emerging AI-native linters are beginning to surface maintainability signals — duplication rates, cognitive complexity scores, naming quality, performance regression patterns — directly in pull request reviews. The next evolution will be AI models that are explicitly optimized not just for functional correctness but for the long-term structural health of the codebase they touch. Until that bar is reliably cleared, the responsibility falls where it always has: with the engineer who reads the diff and decides whether to merge it.
Write code as if a psychopath will maintain it. Or better yet, write it as if you will — six months from now, in a hurry, with no memory of why you made the choices you did. In the age of AI-assisted development, that principle is not just good practice; it is a prerequisite for keeping your codebase sane.
Topics
Comments(0)
No comments yet. Be the first to share your thoughts.
Join the conversation
Your email stays private and comments are reviewed before appearing.


