Retrospective design is not a sin

Sean McGrath suggests that you should implement first and design later:

A design phase, wedged between two implementation phases, makes sense if you are doing rapid prototyping. That is, you build something, learn from it and use the experience to create a good design for the real implementation, throwing the prototype away.

This reminds me of two illuminating stories from Mythical Man-Month by Fred Brooks---a frank criticism of overengineered software projects, still sharply relevant some twenty years on---although it puts a different slant on each story. Firstly, it falls under the principle of Plan to Throw One Away:

... Where a new system concept or new technology is used, one has to build a system to throw away, for even the best planning is not so omniscient as to get it right the first time.

The management question, therefore, is not whether to build a pilot system and throw it away. You will do that. The only question is whether to plan in advance to build a throwaway, or to promise to deliver the throwaway to customers.

If you're prototyping rapidly, then your first implementation is intended to inform your first product, and need not be polished in itself. Build to learn; build to play; build to throw away.

At the same time, though, it exonerates the practice of sheepishly preparing flowcharts for your programs long after the program is built, the Flow-Chart Curse:

... I have never seen an experienced programmer who routinely made detailed flow charts before beginning to write programs. Where organization standards require flow charts, these are almost invariably done after the fact. Many shops proudly use machine programs to generate this "indispensable design tool" from the completed code. I think this universal experience is not an embarrassing and deplorable departure from good practice, to be acknolwedged only with a nervous laugh. Instead it is the application of good judgment, and it teaches us something about the utility of flow charts.

From the context, I'm pretty certain that Brooks is being sarcastic rather than ironic in the last paragraph: he refers later to "the obsolete practice of flow charting," so he presumably considers them to be an albatross around the neck of the average programmer, descending upon them from high above only when culture and prissy documentation standards require. But McGrath's idea gives more credit to the---frequently organisationally mandated---instinct to only draw developer diagrams post hoc than Brooks does: such charting could be how you tidy up after the version you're going to throw away, so that you won't have to throw the next version away too.

I occasionally draw flowcharts and basic UML models before I start a long programming jag, but I almost always draw them afterwards, even if they're envelope-sized scrawls that help me remember where we went wrong and right. Part of the reason behind doing that is that we tend to do interesting work---the more irksome the problems, then (just about) the more interesting the solutions---and use interesting technologies, so at the point of completion the technical stack is worth mentally poking at on paper. And part of it is that we often revisit old work as a company, and do show-and-tell sessions.

But mostly it's because I'm only human, and flowcharts---if nothing else---can function as the programmer's equivalent of cave-painting. Abstracting, documentary, narrative: they let us make sense of what might not have made sense at the time; they help us both to remember more coherently and forget more contentedly, just in time for the next job.