There is a famous concept in the writing community, sometimes seen as a grand divide which splits all writers into two opposing camps, which I think applies to programming as well.
Before we start, it’s important to note that reality is nuanced. These camps are the extreme ends of a broad spectrum, and most people belong somewhere in the middle.
The most common terms for these two camps are architects and discovery writers. Since I’m a writer at heart, this mixed metaphor really grates on my nerves—I always refer to them as architects and explorers instead.
Architects are people who plan ahead. They draw up their grand design, perfecting every last detail before they ever put pen to paper and write some prose. If the design doesn’t work when confronted with reality, they go back to the drawing board and fix the plan itself before continuing.
Explorers are people who go on an adventure without even the barest sketch of a map. They set out from their starting point with no clue where their story might end up, and every step along the way is as much a surprise to them as it is to their readers. If they get stuck, they retrace their steps and try a different road.
It’s important to note that these approaches are equally valid. Both can produce incredible stories, and with a little work on either side you can barely tell the difference between the two when looking at the end result.
To give a couple of well-known examples, one author who is particularly outspoken about being an explorer is George RR Martin, while another who is well-known to be an architect is JK Rowling. You can see how their different approaches colour the way their stories are told, yet both writers have written incredibly successful and well-loved stories.
And, as mentioned before, in reality most people blend the two approaches together.
So how does that apply to software?
Generally speaking, engineers are given a set of requirements or a problem statement (or freedom to find their own), and asked to build something which works.
Many engineers like to plan first. They start by sketching diagrams on a whiteboard, then perhaps design an interlocking system of types which define their chosen interfaces, and then write the code which actually implements their solution.
Other engineers prefer to dive straight in to the code. They explore the problem space via experimentation with real code, false starts, and intuition, and then refine their path and build up a more robust and clear solution over time.
Again, many people are a mix of the two. It’s common practice to explore the problem space first, then throw away the exploration code and architect a more permanent solution based on the insight gained.
In spite of this, in my experience people often assume that programmers are architects first and foremost. That assumption then leads to miscommunication.
Interestingly, one person can sit on different sides of the divide for different things.