Being a good Programmer
To the careless reader this blog might look like yet another post discussing how A.I. may or may not be the end of software engineering and programming.
But that’s only if you read it on the surface. The underlying question we’ll actually tackle is what makes a good programmer in the first place, regardless of A.I. or not. I’ll argue that the underlying principles of being a good programmer in the age of A.I. are very much the same as they were before A.I.
What is different today is the rate of change. It’s extremely rapid, and therefore the gap between good and bad programmers is growing even wider. Good programmers will be a lot more productive than before, while bad programmers will stagnate.
Note that I don’t think the current level of A.I. will lead to a fundamental shift where we all go on holiday to the beach and let A.I. overlords write code for us and run our companies. Rather, I think this progress will lead to a huge acceleration in programming itself and in the potential capabilities of programmers.
Welcome to my fifteenth post in the Advent of Writing series.
Let’s dive in.
Programming is building theories
Let’s start with this quote:

…the proper, primary aim of programming is, not to produce programs, but to have the programmers build theories of the manner in which the problems at hand are solved by program execution.
If there’s only one thing you remember from this blog, let it be this.
Unfortunately, when we learn programming as a craft and as a tool, we immediately skip over the step where we build a theory. You’re given an assignment: “build a note-taking app using React and MongoDB,” or something more theoretical like “how can we improve the worst-case O(n) time complexity here?”
None of these assignments are bad per se. Both are important things to know and understand how to solve. The problem is that theory building is rarely exercised in formal education. Unfortunately, it’s rarely exercised on the job either.
But the best companies require you to do it all the time, especially in more senior roles. Your job is to understand the world of the user: their needs, desires, and problems. And importantly, whether there’s any business value in solving those problems at all. Only once you have a theory and a solid business case do you proceed with the actual technical implementation.
Then you discover that your theory was somewhat wrong, and you iterate the software with your updated beliefs. And in some cases you need to build first to even have a theory. However you form your theory doesn’t matter much.
Just to remove any ambiguity: the technical implementation does still matter, a lot. You can’t just hand-wave it away. The important takeaway is that theory building precedes technical implementation. A technical implementation without a theory is nothing. But equally, a theory with a bad technical implementation won’t get you very far either. It might even send you down the wrong path, where you think you’ve (dis)proved your theory, but in reality you just built something that never properly expressed it.
A.I. is another layer (albeit a powerful one)
In the early days people wrote programs on punch cards, then machine code and assembly. From the 50s onward, high-level languages like Fortran, COBOL, and later C emerged. In the 90s we started developing even higher-level languages like Java and Python. Nowadays, a web developer rarely even writes plain JavaScript, but instead TypeScript inside a framework, which then gets compiled down to plain JS.
For better or worse, we’ve abstracted ourselves very far away from punch cards and assembly.
The modern programmer doesn’t (mostly) need to think about memory allocations in JavaScript. It’s all abstracted away by the runtime and engine you’re using. Occasional memory leaks might happen, so it’s good to understand the concept and how to debug them. But for most of the day, you can ignore it. And this is a good thing, it allows us to focus on delivering software faster to users without worrying about lower-level details.
The important aspect is trust. If V8 had memory corruption issues once per hour, it wouldn’t work as a reliable building block in our tower of abstractions. A.I. is another building block in this tower. Just another layer up again. Now we don’t even need to write the React code ourselves anymore, we can instruct the A.I., review the output, and maybe nudge it in the right direction.
Unfortunately, A.I. isn’t yet as reliable as something like the V8 engine. In some cases we’re simply thrown back down the stack and end up wasting time fixing what the A.I. wrote. But this isn’t inherently an A.I. problem. There are still cases where C compilers don’t produce performant enough code, and programmers drop down to analyzing assembly output or resort to intrinsics.
This problem exists at every level of the abstraction tower.
Don’t mind the tower
The point of the examples above is this: if you were a programmer who was good at building theories from the beginning, you’ll realize that it doesn’t really matter which part of the abstraction tower you’re working in.
At every layer, you still need to decide, judge, and apply taste to what should be built. And importantly, you need to be able to revise and change your opinion. Judgment survives abstraction.
What A.I. does change:
- Iteration speed: you can verify and test theories much faster.
- Tooling: learning new tools and programming languages becomes significantly easier.
Build theories
This would be a flat blog, ranting endlessly about the importance of building theories, if I didn’t at least give some concrete action points on how to actually do that.
Needless to say, I’m not an expert in this area. I’m just a programmer with an opinion, which I guess is the first step in building theories. For many things, you probably have better intuition than you think. We’ve all used software that sucks to use, and software that’s invisible and just works.
Next time something does, or doesn’t, get in your way, ask why. Then dig deeper.
Beyond that, books like The Mom Test are quite good. They help you learn how to ask better questions and uncover what people really want, as opposed to what they say they want.
Keep building!