In Medias Res
One piece of advice to overcome writer’s block is to “try beginning in the middle”. This frees you from getting bogged down in all the mechanics of the story: all the tedious setting up the characters, names, places, etc..
Instead you can focus on the important things like where you want to end up and why you wanted to write the story in the first place.
In the humanities in medias res is the Latin phrase used to say “it begins in the middle.” Homer’s Odyssey begins in medias res. The reader joins Odysseus halfway on his journey back to his wife in Ithaca.
The point is that the journey is the interesting bit: we don’t care how he came to be so far from Ithaca in the first place.
Recently, while working on a software project, I was reminded of this phrase. I found it remarkable how the advice to “try beginning in the middle” could apply as much to software as literature. After all, software is one of liberal arts.
In software the idea of beginning at the middle is fundamental to what is known as test-driven development. Before you write functional code, first you write tests that setup different scenarios and assert that you get a particular result.
At first all the tests will fail, but will begin to pass once you fill in the implementation details. At the end, all the tests should go green and you can be happy that your code fulfils the specification.
Or at least, it should work this way. I say this as I used to think test-driven development was only about the specification. I now realise it is more integral to the design of the code itself. I learned this the hard way.
My mistake was assuming that I could create a high-level design on paper. I went on to develop components of a system in isolation, confident that they would work together in a design I had imagined.
As I got to the end, the components worked, but they didn’t fit together properly, and in some cases did not contribute to the purpose of the code. I had assumed that the integration at the end was the easy part, and that my untested high-level design would be enough
What happened was that the code turned out like a new suit, which had a jacket that was a little too tight and trousers two inches short.
So I started again, at the beginning: setting up mocks at the level I thought was too high for tests to be useful. At this level, I wrote code that read like a natural language and focused entirely on how I wanted the system to work.
Freeman and Pryce write about this style of programming and design in Growing Object Oriented Software Guided by Tests:
We like to start by writing a test as if its implementation already exists, and then filling in whatever is need to make it work – what Abelson and Sussman call “programming by wishful thinking”. Working backwards from the test helps us focus on what we want the system to do, instead of getting caught up in the complexity of how we will make it work.
After refactoring the code, I noticed that there was a clearer cascade to the tests: from high abstraction, to low level implementation. The high-level acceptance/feature tests meant that the code was a lot clearer for peer-review, as they were very similar to requirements written in natural language on the story.