Back to Blog

The Lost Virtue of Laziness: Building Simpler Systems in the AI Age

EN 🇺🇸Article•8 min read
#AI#Software Engineering#Abstraction#Technical Debt#LLM#Best Practices#Design Principles

In an era where large language models (LLMs) can generate thousands of lines of code at the push of a button, a silent, insidious threat emerges: the erosion of engineering discipline. The sheer ease of code generation often overshadows the fundamental principles that lead to robust, maintainable, and scalable systems. We risk losing sight of the very human virtues that traditionally compelled us towards elegant design.

One such endangered virtue is what programmers playfully call "laziness" — not true idleness, but a profound drive for abstraction and efficiency. This article dives into how AI challenges this core engineering value and outlines strategies for reclaiming it, ensuring we build simpler, better systems in the AI-assisted future.

What "Laziness" actually is

In software engineering, laziness isn't about avoiding work; it's about avoiding unnecessary work, especially in the future. It’s the deep-seated impulse to write less code, to create more powerful and reusable abstractions, and to automate repetitive tasks. This virtue, famously highlighted by Perl's creator Larry Wall (alongside hubris and impatience), drives us to solve problems once, elegantly, rather than repeatedly with verbose, brittle solutions. It manifests as a constant push for simplicity and elegance.

LLMs, however, operate without this constraint. They don't experience the cognitive load of future maintenance, the frustration of debugging complex systems, or the personal cost of refactoring. Their "work" is free, leading them to prioritize immediate output over long-term architectural health.

Key components

Here are the essential elements of this engineering "laziness" and how AI interacts with them:

Consider a common scenario to see this concept in action:

  1. Human Engineer's Process (driven by laziness):
    1. Identifies Repetition: Sees three distinct functions for parsing slightly different log formats.
    2. Seeks Abstraction: Designs a single, configurable parseLog function, parameterizing the format differences.
    3. Refactors and Simplifies: Replaces three specific functions with one generic, reusable abstraction, reducing total lines of code and future maintenance.
  2. Unconstrained AI's Process (lacking laziness):
    1. Generates First Function: Creates parseLogFormatA perfectly matching the initial prompt.
    2. Generates Second Function: Creates parseLogFormatB when prompted for the second format, without automatically identifying commonalities.
    3. Generates Third Function: Creates parseLogFormatC, perpetuating the pattern of duplication and leading to a "layercake of garbage" if left unchecked, increasing complexity rather than reducing it.

Why engineers choose it

Embracing this disciplined "laziness" offers profound benefits that directly counter the pitfalls of unchecked AI-generated code. It's not merely about writing less, but writing smarter.

The trade-offs you need to know

While the "virtue of laziness" promotes simplicity, ignoring it with AI doesn't remove complexity; it merely shifts and often amplifies it, creating new forms of technical debt. This shift can lead to subtle but significant long-term problems.

When to use it (and when not to)

Understanding when to apply human-driven "laziness" (i.e., intentional abstraction and simplification) and when to let AI take the reins for raw generation is crucial.

Use it when:

Avoid it when:

Best practices that make the difference

To effectively harness AI without sacrificing the quality and maintainability of our software, engineers must proactively integrate human virtues back into the development process. These practices help guide AI towards better outcomes.

Embrace Deliberate Abstraction

Actively seek opportunities to simplify, generalize, and encapsulate complexity, even when AI suggests a direct solution. This involves pausing after AI generation to ask: "Can this be simpler? Is there a pattern here I can abstract?" Always push for the most concise, yet clear, solution.

Prompt with TDD Principles

Apply Test-Driven Development (TDD) not just to the code, but to your interactions with AI. Start with clear, executable tests or desired outcomes for the AI's output. Then, instruct the AI, and use a "reviewer agent" (either another AI or human) to verify the results against your criteria, including documentation and clean code.

Engineer AI for Doubt, Not Just Decisiveness

Train and prompt AI agents to exhibit caution, ask clarifying questions, or defer decisions when uncertainty is high, rather than blindly providing a definitive (and potentially incorrect) answer. Design systems where AI inaction or escalation is a viable and sometimes preferred outcome in ambiguous or high-stakes situations.

Measure Simplicity, Not Just Volume

Shift focus away from raw lines of code or output speed. Instead, prioritize metrics that reflect system health and human cognitive load, such as cyclomatic complexity, depth of inheritance, test coverage, and ultimately, developer satisfaction and velocity on new features. Reward elegant solutions over voluminous ones.

Wrapping up

The advent of AI-powered code generation presents a fascinating paradox. It empowers us to create more code faster than ever before, yet it simultaneously threatens to undermine the very engineering virtues that prevent our systems from collapsing under their own weight. The "virtue of laziness" – the relentless pursuit of elegant abstraction and simplicity – is not a relic of a pre-AI past, but an essential skill for the future.

As software engineers, our role isn't just to use AI, but to guide it. We must be the custodians of architectural quality, instilling human wisdom into the mechanistic output of our tools. By consciously cultivating practices that prioritize simplicity, abstraction, and even strategic doubt, we can ensure that AI augments our craft rather than dilutes it.

The future of software development isn't about how much code AI can write, but how much thoughtful, maintainable code we can architect with AI's help. Let's build that future with deliberate laziness and uncompromising quality.

Newsletter

Stay ahead of the curve

Deep technical insights on software architecture, AI and engineering. No fluff. One email per week.

No spam. Unsubscribe anytime.

The Lost Virtue of Laziness: Building Simpler Systems in the AI Age | Antonio Ferreira