The developer refactored ruthlessly, eliminating all complexity.
Every function was pure, every variable named perfectly.
The senior developer looked at the pristine codebase and asked, “What dirt did you clean away, and where is it now?”
And, “If the code is perfectly clean, what is it clean of?”
Understanding the Koan
The pursuit of clean code is one of our field’s most cherished values, yet this koan invites us to examine what we actually mean by “clean.” When we eliminate duplication through abstraction, we haven’t destroyed the complexity—we’ve transformed it from explicit repetition into implicit patterns that require cognitive overhead to recognize and understand. When we extract methods to make functions smaller, we trade line count for call-stack depth. When we create elegant interfaces, we hide implementation details that someone, somewhere, will eventually need to understand.
In infrastructure work, this manifests in particularly tangible ways. Consider the evolution from manual server configuration to configuration management tools to infrastructure-as-code to cloud-native abstractions. Each layer adds elegance and power, but also creates a distance between the developer and the underlying reality. When things work, this distance is freeing. When they break, it becomes a chasm that must be crossed with insufficient maps.
The koan’s first question—”What dirt did you clean away, and where is it now?”—points to the conservation of complexity in software systems. The “dirt” might be conditional logic that’s now encoded in your class hierarchy. It might be state management that’s been pushed from your code into your database or message queue. It might be configuration that’s moved from hard-coded values to environment variables to configuration services to service meshes. The complexity remains; only its location changes.
The second question strikes deeper: “If the code is perfectly clean, what is it clean of?” This challenges our fundamental assumptions. Clean of what—duplication? Conditional branches? Comments? Long functions? Each thing we clean away took complexity from one place and distributed it elsewhere. Code “clean of” comments might require perfect naming, which itself demands shared vocabulary and context. Code “clean of” conditionals might employ polymorphism, moving the branching logic into your type system and object instantiation.
This isn’t an argument against refactoring or clean code practices. Rather, it’s an invitation to develop awareness about the trade-offs we’re making. Some transformations of complexity are worthwhile—moving business logic out of stored procedures into application code generally improves testability and maintainability. Some are less clear—extracting every three-line operation into its own named function can make code harder to read despite technically being “cleaner.”
What matters is consciousness about where complexity lives in your system. When you abstract, be intentional about where you’re moving the complexity and whether that new location serves your team and your system better. When you read “clean” code that feels hard to understand, ask yourself what’s been cleaned away and where it went. When you review code that feels messy, consider whether the mess is inherent to the problem domain or whether it can be meaningfully relocated.
The teaching here is about honest accounting. Clean code is beautiful and valuable, but perfection is a red flag. If your codebase appears to have no complexity, you haven’t eliminated it—you’ve just hidden it so well that you may have lost track of where it went. And that’s when production breaks at 2 AM and no one can find the thread that leads back to understanding.
