6 min read
Incantations

When I first learned how to code, it felt like magic. I typed almost-english-sounding words into a computer and it magically gave me the result I wanted. Python was my first language and perhaps that even amplified the effect, with its beginner-friendly syntax and high level scripting capabilities. print(2 + 3) read like english and did exactly what it sounded like. If I needed to interact with a file on my computer, it was as simple as file = open(path). If I needed to fetch data from an API it was as simple as requests.get(url). I had no understanding of how the computer was achieving any of this, how a piece of metal with barely a trickle of electricity was able to perform any arbitrary action that I could type. All I knew was that if I typed the right thing into python, it could do anything. I just needed to know the incantation and the computer would perform the magic.

A few months later I started programming in C and C++ and the magic quickly got demystified. I learned what a CPU was and how it was able to perform logical and mathematical operations. I learned how a program was loaded into the CPU’s memory and how it got executed. I learned what machine code was and how it was generated by compilers from english-sounding programming languages. I learned what kind of capabilities operating systems provided and what kind of convenient helpers standard libraries provided. I peered behind the magician’s veil and saw through the illusion.

And just as a child is disappointed when they first learn magic isn’t real, I was too. But that feeling was short-lived and was quickly replaced with excitement and enthusiasm. Now that I knew how the magic worked, I could create it. I lost the sense of awe and wonder, but gained the ability to create whatever I wanted without limitation. I didn’t have to learn an incantation to make the computer perform an action, I could figure out how the computer should achieve it and then program it myself. A line cook follows recipes, but a chef creates those recipes. A cameraman shoots scenes but a director creates those scenes. I was no longer limited to being a line cook or a cameraman, I could now be a chef or a director.

Over the next decade, as I became a full-time professional programmer and worked in several domains including web dev, mobile dev, gamedev, infrastructure, and much more, I always strived to peer behind the magician’s veil and figure out what the computer was doing underneath. I didn’t just use web server frameworks, I learned how a computer receives a request over the network and how it responds to it. I didn’t just use game engines, I learned how a computer performs all the game logic and converts it to an audio and video output at incredible speeds. I didn’t just learn how to deploy to a cloud provider like AWS, I learned how cloud infrastructures work and how I could deploy on my own given just a computer and the internet. I wrote MIPS assembly code to build an intuition for how computer worked and how to think like a computer. And I assumed that all experienced programmers did the same. Surely you needed to have a deep understanding of computers to be an effective programmer.

I was wrong.

For the past 2-3 years, I’ve noticed an alarming trend of experienced professional programmers who seem to have no idea of how computers work, and seemingly have no interest in the matter either. Perhaps it was always this way and I simply never noticed it. But I suspect this is indeed a real trend, and one that will only increase over time. With AI coding on the rise, programming is now accessible to anyone, even those who have no idea of how computers work. And AI coding is indeed like casting incantations. When you type print(2+3) into python, you can follow the steps starting from that statment all the way down to the machine code which runs on the hardware. But there’s no direct chain from telling an AI print the sum of 2 and 3 and what happens on the hardware. LLMs are statistical next-word-prediction engines. You cannot know what it will do. Yes, you can inspect the program it generates, but there is a black box between your instruction and that step. It is a veil you cannot peer through. But perhaps more importantly, it is a veil you don’t have to peer through. You can continue programming as if it is magic. If your incantation doesn’t produce the output you wanted, you don’t have to figure out why it didn’t work. You just cast another incantation and hope it works this time.

This chain-of-incantations is exactly the workflow of AI coding. I have written before about why I don’t use AI because I don’t enjoy this process. I enjoy the process of figuring out how to make a computer perform an action, I’m not interested in casting incantations. I’m a software engineer and I enjoy building programs brick by brick. John Raines made the distinction between a frameworker and an engineer. But the difference between an AI coder and an engineer is many orders of magnitude higher.

I recently started hearing the phrase “I programmed this myself”. People have started to make the distinction between code they write and code they cast as incantations into an AI. We are moving towards a world where more and more code is not written but instead cast as magic spells. Some of my coworkers cannot describe what their code does and cannot identify the root cause when a bug appears. They cannot tell early in a program’s life which patterns will hold in the long run and which will fall apart. They do not know the difference between a good and a bad way of solving a problem. And they don’t care. It’s just magic, after all.