The Diminished Joy of Programming with AI and Large Language Models

Software Development

Exploring how the increasing integration of AI and Large Language Models in programming can paradoxically erode a developer's joy, transforming problem-solving satisfaction into a cycle of frustration and unmaintainable code.

Connecting with my dogs brings me immense pleasure, a simple joy that I believe enhances my focus and productivity. Paradoxically, after extensive experimentation, I now contend that AI and Large Language Models (LLMs) are progressively draining the inherent joy from programming. My trials have included advanced auto-completion, as well as AI agents integrated into my IDE, CLI, and GitHub's server-side environment. This direct experience has solidified my opinion: the current state of AI-driven programming is, to put it mildly, disappointing.

I embarked on my programming journey around the age of 15, and for approximately 28 years, it has been a source of profound satisfaction. The greatest gratification stems from seeing a solution finally work precisely as intended, a culmination of gradually building a deep understanding of the problem domain and the underlying algorithms. It's not merely about reaching the destination, but the invaluable journey of getting there. There is unparalleled satisfaction in mastering a complex algorithm or technique, or achieving a breakthrough in comprehending a challenging problem.

Conversely, the most disheartening aspect of programming is when things fail due to trivial oversights or an incomplete understanding, often resulting from blindly adopting suboptimal solutions. Concurrency and performance issues, in particular, are notoriously frustrating given their non-deterministic nature and the scarcity of easily accessible, comprehensive documentation. This often leads to a desperate, trial-and-error approach, which can only be described as "shooting bullets in the dark."

When an LLM-driven agent is tasked with a problem, it typically handles the straightforward elements with ease. These might involve tedious interactions with a proprietary third-party API, but they remain simple tasks. However, when confronted with the more challenging aspects, the agent often fails, and fails spectacularly. My initial impulse is to provide high-level feedback, outlining the mistakes and the desired next steps, entering into a slow and error-prone feedback loop. I then observe the LLM fail again. Yet, because it successfully navigated the easy parts, I feel compelled to grant it another opportunity, only to witness it falter, often more severely, a second time.

Frustrated, I inevitably resort to checking out the code myself. At this point, I’m confident I can investigate and devise a reasonable solution. However, I often discover the generated code to be ... difficult to maintain, even outright subpar. The insidious nature of this problem is that the code doesn't appear problematic in its initial pull requests. Instead, "crap" (including equally poor comments) gradually accumulates because I become hesitant to instruct the LLM to improve maintainability, fearing an even higher probability of introducing further errors.

Even when the AI-generated code eventually functions, I am left with a pervasive sense that I could have delivered a superior solution, a feeling that extends to all but the most insignificant scripts.

Ultimately, an LLM-driven workflow tends to deliver all the negative aspects of programming: the stress of losing control when things go awry, the desperate "shooting bullets in the dark" to fix unmaintainable code, and none of the genuine gratification that arises from the problem-solving journey itself. We are, in essence, replacing that invaluable journey and its accompanying learning with a frustrating dialogue with an inconsistent and often obtuse digital assistant.