by Serguey Shinder
There was a module I inherited that I hated on sight. It was tangled, oddly named, full of decisions I could not understand and did not agree with, and every time I had to touch it I left convinced that the honest thing to do was to throw it away and write it properly. Eventually I got permission to do exactly that, and I began the rewrite with the particular joy of a person who is certain he is about to fix something.
The new version came together quickly, and it was beautiful. Clean, obvious, named the way I would have named it, structured the way I would have structured it. For about a week I felt vindicated, and then the bug reports started, and they were strange. Edge cases I had never heard of, inputs I would never have thought to handle, behaviors that made no sense until I went back and read the old tangled code and found, buried in its ugliness, the exact handling for the exact case that was now failing.
The old module was not badly written. It was scarred. Every ugly branch I had sneered at was a healed wound, a fix for some real problem that some real user had hit, and the tangle I had dismissed as incompetence was actually years of accumulated knowledge about how the world actually behaved rather than how I assumed it did. I had mistaken the record of hard-won lessons for a mess, and I had thrown the lessons away along with the mess.
My clean rewrite was clean precisely because it was ignorant. It handled the cases I could imagine, elegantly, and it had no idea about the cases I could not, which were the ones the old code had been quietly absorbing for years. The beauty of my version was the beauty of a thing that has not yet met reality, and reality was now teaching it the same lessons, one painful bug report at a time, that the old code had already learned.
I did not abandon the rewrite. But I stopped treating the old code as an enemy and started treating it as a witness. I went through every ugly branch and asked what it knew, and I carried that knowledge forward into the clean version, which stopped being quite so clean and started being correct. The scars came back, better organized, but present.
Now when I meet code that looks worse than I would have written it, I assume it knows something I do not, at least until I have proven otherwise. Ugliness is sometimes just ugliness, but often it is memory, and rewriting without reading is not improvement. It is forgetting, done confidently, and then relearning everything at the users' expense.
– Serguey Asael Shinder
Leave a Reply