the art of programming why i was wrong about llm
two years ago, i wrote a blog on the art of programming and why i won’t use llm. it became viral, and it ranked #2 on hackernews at some point. i received lovely emails from people who resonated with blog. i wrote the blog under the pretense that llms would take away the fun of architectural thinking and the problem solving away from programming. it stopped me from giving llms a try. my stubbornness made me cling to my workflow and forced me to come up with superficial, artistic justifications for me to remain still.
what changed?
i have since learned that llms are only as good as the user who wields them. a person who asks an llm to “build me a beautiful website make no mistakes” is guaranteed to receive dissatisfactory. it is a directionless prompt which leaves the llm no choice but to regress to the mean.
an llm cannot replace good technical and artistic judgements which are products of one’s cumulative experience. llms will and regularly make obvious (to us) mistakes and distasteful judgements. it is up to the user to, spot them, take ownership and course correct accordingly.
how was i wrong?
in the original blog, i claimed “using llm to write code is like asking an artist to paint for you.” this statement holds true only if llms are on equal-footing as competent engineers, but they are not! they lack the experience and the technical taste of one. using llm to write code does not mean delegating the entire process of programming to it. instead, it is a collaborative process, where ideas are bounced back and forth and code refined iteratively.
i also equated the use of llm to the lack of care and attention. in reality, it allows me to care more. llms have caught edge cases and bugs that i otherwise would not have, which enables me to build more resilient software. the truth is that cares are afforded independent of the tools utilized in the process. it is a mindset and bar one set for themselves.
maximize fun
there are parts of engineering that is unfun, at least to me: scaffolding yet another REST backend and wiring up all the services; coming up with test data; building CI/CD pipelines; the list goes on. they are repetive and unimaginative, but they are an important and necessary part of the workflow. having llms to the chore for me allows me to focus on the fun parts of engineering, like designing and orchestrating systems, coming up with novel solutions for niche problems, tweaking UI elements so that they look pixel-perfect, learning new things, etc.
in fact, that are times when i choose not to use an llm for coding. one of them is when building novem, a gpui-based github pr reviewer. i love writing rust, and i want to learn gpui. having an llm write the code for me makes no sense when i am interested in the granular details. what i do use llm for in this case is using it as a tutor. it enables me to learn gpui quicker and more in depth, because it is able to navigate through the gpui codebase with ease.
competence cannot be replaced
i repeat: llms are only as good as the user who wields them. they are not crutches to one’s skill and knowledge gaps. a person with no design taste is not going to be able to prompt their way into a meticulously crafted user interface. they are, however, amplifiers of one’s abilities when used with care. it has enabled me to build with more confidence and take on more tasks, but never have i once delegated my problem solving to them. it has enabled me to learn new things faster and more in depth.
in a world full of slop, it takes competence and judgement to discern treasures from disposable waste. only through trails and tribulation can the two be cultivated.