We don’t write code in the same way that we think about it."
The job of a developer exists at the intersection of abstraction and practicality and we are expected to be able to move between them easily. The problems we need to solve are where we start, and the first stages of any project are always general and wide.
“How can we begin to approach this? What will the thing we are going to build do?”
This broad-strokes approach begins every project. It might be a thirty minute meeting with your team about one of the day’s big tickets; months of planning for a new company or even ten seconds before you start to write a simple script.
And then we start to bring in some of the practical issues. Considerations which mean that we might not be able to solve the problem in the optimal way.
What would be the best way to write this? What way would integrate easiest into our current systems? How are we going to deploy it?
These steps can be more frustrating. We have a framework in mind of how to deal the problem but now we might have to rethink. Perhaps we need to send some emails or have meetings specifically on this. The problem is no closer to being solved.
Finally, we get to the real practicalities.
How are we going to build this?
Here we put finger to keyboard and start programming. With any luck, most of the conversions between abstract ideas and practicalities have become second nature with experience. We don’t need to think of each letter or line we write, we understand the meaning of what we are writing and that’s enough, but it’s only a matter of time before something breaks.
Each time we learn a new language with an unfamiliar syntax, we are reminded that what we write is not the same thing as the abstract program we had in our heads. When we have to go back to look for a typo, or encounter someone else’s inexplicably confusing code, we have to swap from thinking in abstraction to thinking in concrete.
We don’t write code in the same way that we think about it, because what we imagine is abstract and perfect, clever solutions to devious problems, and what we write is concrete, constrained by the practical and impractical measures someone else took to make what you are now building with. Each time we have to swap between the two jobs, we break the flow of our work and in the end, we build less.
We write code like we do because that was the most convenient way to build languages in the 1970s. The paradigm hasn’t shifted since then. Of course, the paradigms of languages themselves have progressed, but how we write in a language has not and that’s why the problem persists.