There is a lot of debate in the software community around whether LLMs can replace developers. Part of the reason is the way we formulate the problem of what it means to write software. In industry, we still give outsize cultural deference to software developers as lone wizards who come into the room, put on their hoodie, crank up the techno, and write the application on their own. (View Highlight)
When we sit down at our keyboard, we assume that we sit down alone, with our precious treasure trove of programming knowledge that we have built up over the years, hoarding the nuggets about byte size and data types like a dragon guarding its gold. It is us and our hard-earned brain patterns from years of algorithm classes and hundreds of pages spent trawling StackOverflow versus the machine, working alone, against each other. (View Highlight)
We sit down, we crack our knuckles and deserialize the knowledge from our brain into clear streams of beautiful code, in solitude and blessed silence. These days, we are spending less time with books and search results and more time with ChatGPT or Claude, and it’s this prompting process, we assume, that will ultimately replace us. But that’s only true if we consider the developer as an individual unit of work separate from anything else, without our own context window. (View Highlight)
When we ask LLMs to write code, we get back compressed representations of the entire field, optimized via RLHF, sorted by descending probability, and limited by the size of the model’s context window. So we are not alone, but we are also often don’t ascend outside a local minimum of average code, sometimes not even outside the local minima of suckiness. Not to mention, these models have no access to hundreds and thousands and millions of lines of elegant code that has never seen the public internet because it sits quietly, undiscoverable in corporate git servers. When we ask the model, almost any model (with the exception of finetunes on our own data), we are peeking into a very small window of what good code could be. (View Highlight)
When I sit down at the keyboard, I also sit down with the average of the local minima, but I also have a secret superpower. I’ve had the enormous good fortune to work with and learn from very good developers, and it’s the average habits of all of these developers that lift me out of the depths of compressed scraped GitHub. (View Highlight)
These developers’ good habits stream from my memories into my consciousness. As I write code, they enrich my decision-making process, like a radio station of good advice that never turns off. (View Highlight)
A insists that I need to learn fundamental algorithms and data structures inside and out because they are the basis for what makes good code fast. “Even if you never implement a LinkedList in your own code, you’ll be able to more clearly reason through the decisions others have made and use the libraries that make the most efficient use of them.”
B tells me, through hundreds of PR comments over years and years, that it’s not good enough to have a PR that just passes tests. The code needs to be clean, reasonable, and legible for others because we read code more than we write it.
C tells me to write code that is elegant. C says it will take longer to write this kind of code than something that just ships, but that it is our professional responsibility as developers to carve out that time, to demand it. “Write your code, then write a second time. Make it work, make it right, make it fast.”
D tells me not to mess with fancy tools. A simple print debug statement goes a long way. A 2-line unit test fixes 100 lines of obtuse code. Code completion editors don’t work when you don’t know what you want to autocomplete, yet.
E tells me to master my tools, to dig into problems I don’t understand, to get to a reproducible example, to play with things in the terminal, take them apart, write smaller and smaller pieces of code until they make sense.
F tells me to take time to analyze the data correctly, and to be crisp and concrete about my analysis. (View Highlight)
G and H tell me to start without machine learning if I can, and if I have to use it, to use a simple model first of all.
I tells me to get to a local development loop as soon as possible.
J tells me to take my craft seriously, but never myself.
K tells me to be patient and have grace, both for others, and for myself. Code is hard, but humans are harder. (View Highlight)
Over and over my Alphabet Radio plays my greatest hits, fixing a variable name, digging through a class hierarchy, adding a test, using dependency injection, avoiding unnecessary libraries, deleting lines of code until the number of lines I add is less than the number I subtract, refactoring, refactoring, refactoring. (View Highlight)
I am so lucky to have my Alphabet Radio. Engineers like me who come from data land sometimes don’t get the privilege of building a playlist like this because we don’t work in teams, and for a long time at the beginning of my career, I was one of these people. (View Highlight)
It was very lonely and I felt wrong a lot of the time without guardrails or intuition as to why what I was doing was inefficient and incorrect. LLMs don’t and can’t help with this part. Repeated exposure to the best practices of good developers does. (View Highlight)
Nothing is black and white. Code is not precious, nor the be-all end-all. The end goal is a functioning product. All code is eventually thrown away. LLMs help with some tasks, if you already know what you want to do and give you shortcuts. But they can’t help with this part. They can’t turn on the radio. We have to build our own context window and make our own playlist. (View Highlight)