Goodbye, clean code (2020)

Efforts to rigorously apply “clean code” principles like DRY and aggressive abstraction can backfire, many engineers argue, when they reduce flexibility and make future changes harder rather than easier. Commenters contrast duplicated but straightforward, domain‑specific code with abstracted versions that entangle unrelated cases, increase cognitive load, and often reflect premature attempts to generalize from too few examples. A recurring theme is that maintainability depends as much on good judgment, communication, and context‑aware tradeoffs as on any specific style rules or design dogma.

Clean Code, DRY, and Abstraction

  • Many argue the refactor failed because it created a bad abstraction, not because “clean code” is inherently bad.
  • DRY is seen as a guideline: it’s valuable when multiple places should always change together; harmful when it forces unrelated cases into one pathway.
  • Several comments stress “abstract bottom‑up, not top‑down”: first let concrete use‑cases accumulate, then factor out simple, obvious helpers.
  • A recurring heuristic: duplication of knowledge or behavior merits abstraction; superficial similarity in code shape often does not.

When Duplication Is Preferable

  • Multiple posters say “duplication is cheaper than the wrong abstraction.” Wrong abstractions become brittle, add conditionals and special cases, and are hard to unwind.
  • For evolving domains (graphics, finance products, complex business logic), keeping separate but similar code paths often preserves flexibility for future divergence.
  • Some point out that editing the same logic in a few places is rarely the real cost driver; debugging a tangled abstraction often is.

Assessing the “Clean Code” Canon

  • Some criticize the “Clean Code” style as dogmatic, under‑caveated, and attractive to juniors who apply rules mechanically (e.g., “lots of tiny functions,” DRY at all costs).
  • Others note the original texts frame recommendations as controversial and non‑authoritative, and insist misuse is reader error, not book error.
  • There is concern that linters and teams have turned flexible guidelines into rigid doctrine.

Team Dynamics and Process

  • Many see the core mistake as social/process: rewriting a teammate’s fresh work at night and committing without discussion or review.
  • Opinions split between “code belongs to the team; anyone may refactor” and “context and etiquette matter; unilateral rewrites damage trust.”
  • Suggested alternatives: review comments, incremental helper extraction, separate PRs with the original author looped in.

Language and Paradigm Perspectives

  • Some praise functional languages (e.g., with Applicative/Monad laws) for standardized, reusable abstractions, reducing project‑specific ones.
  • Others highlight Go’s opposite tradeoff: fewer language‑level abstractions, more duplication, but simpler mental model.
  • There is debate over object‑oriented hierarchies for geometry (e.g., squares vs rectangles) and how mutability breaks naive abstractions.

Testing, Maintainability, and Practicality

  • A camp argues heavy testing would have enabled “fearless refactoring” and made the change uncontroversial.
  • Others respond that tests don’t solve cognitive complexity or social issues; aesthetically or structurally bad code can be fully tested and still harmful.
  • Broad agreement: maintainability, clarity of business logic, and ease of change outrank aesthetics or line‑count reduction.