Is AI the end of software engineering or the next step in its evolution?
Share this @internewscast.com

When I first tried using ChatGPT for coding tasks in early 2023, it reminded me of “The Monkey’s Paw,” a famous horror tale about a cursed object that grants wishes with sinister twists—the wishes come true, but at a cost. Similarly, ChatGPT would make the requested changes by completely altering many unrelated lines as well. The result tended to be overly complex, riddled with irrelevant code snippets. While there were useful lines buried within, sorting through the chaos felt like a distraction.

Initially, using AI-powered tools made me feel out of my league. It was like working alongside an exceptionally intelligent yet overly eager intern, willing to do whatever you ask but with changes you didn’t anticipate. However, when challenged with specific, smaller tasks, it performed astonishingly well.

The key is to keep the scope focused. Not long ago, I used it to optimize some code: instead of sequentially running a dozen lines each taking 40 milliseconds, I had them execute concurrently, cutting completion time to what it took just one line previously. It’s akin to crafting an aircraft with a high-tech 3D printer—to create small, custom parts smoothly versus requesting a complete cockpit, ending up with an unusable deathtrap of misaligned components. Today’s AI models allow even those with minimal coding skills to develop products of varied quality, in what’s dubbed as “vibe-coding.” Google even introduced an app, Opal, specifically for it.

However, vibe-coding isn’t a brand-new concept. It’s part of a long tradition of no-code applications. For programming done with more instinct than logic, many seasoned programmers have relied on a method called “shotgun debugging.” After hours of unsuccessful debugging, a programmer might randomly modify the code—deleting lines, adjusting variables, flipping conditions—hoping it solves the problem. Both vibe-coding and shotgun debugging involve intuitive trial and error, relying more on guesses than on thoughtful analysis.

We’ve used machines to take the load off cognition, but for the first time, we are offloading cognition itself to the machine.

This method isn’t seen as ideal for programmers who take pride in their craft. I soon realized that the most effective way to use AI for coding is through an editorial approach—similar to how this essay was crafted. The editor provided guidelines and I, the writer, delivered a draft that no discerning editor would publish untouched. Before the era of “prompt and pray,” there was just “assign and wait.”

Similarly, a diligent vibe-coder should adopt an editorial perspective. The extensive code generated by AI requires structural adjustment and then meticulous line-by-line improvement. By iteratively refining with prompts—as in several editing rounds—an editor-coder reduces the gap between their goal and the AI’s output.

Often, what I find most useful about these tools isn’t even writing code but understanding it. When I recently had to navigate an unfamiliar codebase, I asked for it to explain its basic flow. The AI generated a flowchart of how the major components fit together, saving me an entire afternoon of spelunking through the code.

I’m of two minds about how much vibe-coding can do. The writer in me celebrates how it could undermine a particular kind of snobbery in Silicon Valley — the sickening smugness engineers often show toward nontechnical roles — by helping blur that spurious boundary. But the engineer in me sees that as facile lip service, because building a nontrivial, production-grade app without grindsome years of real-world software engineering experience is a tall order.

I’ve always thought the best metaphor for a large codebase is a city. In a codebase, there are literal pipelines — data pipelines, event queues, and message brokers — and traffic flows that require complex routing. Just as cities are divided into districts because no single person or team can manage all the complexity, so too are systems divided into units such as modules or microservices. Some parts are so old that it’s safer not to touch them, lest you blow something up — much like the unexploded bombs still buried beneath European cities. (Three World War II-era bombs were defused in Cologne, Germany, just this summer.)

If developing a new product feature is like opening a new airline lounge, a more involved project is like building a second terminal. In that sense, building an app through vibe-coding is like opening a pop-up store in the concourse — the point being that it’s self-contained and requires no integration.

Vibe-coding is good enough for a standalone program, but the knottiest problems in software engineering aren’t about building individual units but connecting them to interoperate. It’s one thing to renovate a single apartment unit and another to link a fire suppression system and emergency power across all floors so they activate in the right sequence.

These concerns extend well beyond the interior. The introduction of a single new node into a distributed system can just as easily disrupt the network, much like the mere existence of a new building can reshape its surroundings: its aerodynamic profile, how it alters sunlight for neighboring buildings, the rerouting of pedestrian traffic, and the countless ripple effects it triggers.

The security concerns around vibe-coding, in my estimation, are something of a bogeyman.

I’m not saying this is some lofty expertise, but rather the tacit, hard-earned kind — not just knowing how to execute, but knowing what to ask next. You can coax almost any answer out of AI when vibe-coding, but the real challenge is knowing the right sequence of questions to get where you need to go. Even if you’ve overseen an interior renovation, without standing at a construction site watching concrete being poured into a foundation, you can’t truly grasp how to create a building. Sure, you can use AI to patch together something that looks functional, but as the software saying goes: “If you think good architecture is expensive, try bad architecture.”

If you were to believe Linus Torvalds, the creator of Linux, there’s also a matter of “taste” in software. Good software architecture isn’t just drawn up in one stroke but emerges from countless sound — and tasteful — micro-decisions, something models can’t zero-shot. Such intuition can only be developed as a result of specific neural damage from a good number of 3AM on-call alerts.Perhaps these analogies will only go so far. A few months ago, an AI could reliably operate only on a single file. Now, it can understand context across multiple folders and, as I’m writing this, across multiple codebases. It’s as if the AI, tasked with its next chess move, went from viewing the board through the eyes of a single pawn to surveying the entire game with strategic insight. And unlike artistic taste, which has infinitely more parameters, “taste” in code might just be the sum of design patterns that an AI could absorb from O’Reilly software books and years of Hacker News feuds.

When the recent Tea app snafu exposed tens of thousands of its users’ driver’s licenses — a failure that a chorus of online commenters swiftly blamed on vibe-coding — it felt like the moment that vibe-coding skeptics had been praying for. As always, we could count on AI influencers on X to grace the timeline with their brilliant takes, and on a certain strain of tech critics — those with a hardened habit of ritual ambulance chasing — to reflexively anathematize any use of AI. In a strange inversion of their usual role as whipping boys, software engineers were suddenly elevated to guardians of security, cashing in on the moment to punch down on careless vibe-coders trespassing in their professional domain.

When it was revealed that vibe-coding likely wasn’t the cause, the incident revealed less about vibe-coding than it did about our enduring impulse to dichotomize technical mishaps into underdogs and bullies, the scammed and fraudsters, victims and perpetrators.

At the risk of appearing to legitimize AI hype merchants, the security concerns around vibe-coding, in my estimation, are something of a bogeyman — or at least the net effect may be non-negative, because AI can also help us write more secure code.

Sure, we’ll see blooper reels of “app slop” and insecure code snippets gleefully shared online, but I suspect many of those flaws could be fixed by simply adding “run a security audit for this pull request” to a checklist. Already, automated tools are flagging potential vulnerabilities. Personally, using these tools has let me generate far more tests than I would normally care to write.

Further, if a model is good enough, when you ask, “Hey, I need a database where I can store driver’s licenses,” an AI might respond:

“Sure, but you forgot to consider security, you idiot. Here’s code that encrypts driver’s license numbers at rest using AES-256-GCM. I’ve also set up a key management system for storing and rotating the encryption key and configured it so decrypting anything requires a two-person approval. Even if someone walks off with the data, they’d still need until the heat death of the universe to crack it. You’re welcome.”

In my day job, I’m a senior software engineer who works on backend mainly, on machine learning occasionally, and on frontend — if I must — reluctantly. In some parts of the role, AI has brought a considerable sense of ease. No more parsing long API docs when a model can tell me directly. No more ritual shaming from Stack Overflow moderators who deemed my question unworthy of asking. Instead, I now have a pair-programmer who doesn’t pass judgment on my career-endingly dumb questions.

The evolution of software engineering is a story of abstraction.

Unlike writing, I have little attachment to blocks of code and will readily let AI edit or regenerate them. But I am protective of my own words. I don’t use AI for writing because I fear losing those rare moments of gratification when I manage to arrange words where they were ordained to be.

For me, this goes beyond sentimental piety because, as a writer who doesn’t write in his mother tongue — “exophonic” is the fancy term — I know how quickly an acquired language can erode. I’ve seen its corrosive effects firsthand in programming. The first language I learned anew after AI arrived was Ruby, and I have a noticeably weaker grasp of its finer points than any other language I’ve used. Even with languages I once knew well, I can sense my fluency retreating.

David Heinemeier Hansson, the creator of Ruby on Rails, recently said that he doesn’t let AI write code for him and put it aptly: “I can literally feel competence draining out of my fingers.” Some of the trivial but routine tasks I could once do under general anesthesia now give me a migraine at the thought of doing them without AI.

Could AI be fatal to software engineering as a profession? If so, the world could at least savor the schadenfreude of watching a job-destroying profession automate itself into irrelevance. More likely in the meantime, the Jevons Paradox — greater efficiency fuels more consumption — will prevail, negating any productivity gain with a higher volume of work.

Another way to see this is as the natural progression of programming: the evolution of software engineering is a story of abstraction, taking us further from the bare metal to ever-higher conceptual layers. The path from assembly language to Python to AI, to illustrate, is like moving from giving instructions such as “rotate your body 60 degrees and go 10 feet,” to “turn right on 14th Street,” to simply telling a GPS, “take me home.”

As a programmer from what will later be seen as the pre-ChatGPT generation, I can’t help but wonder if something vital has been left behind as we ascend to the next level of abstraction. This is nothing new — it’s a familiar cycle playing out again. When C came along in the 1970s, assembly programmers might have seen it as a loss of finer control. Languages like Python, in turn, must look awfully slow and restrictive to a C programmer.

Hence it may be the easiest time in history to be a coder, but it’s perhaps harder than ever to grow into a software engineer. A good coder may write competent code, but a great coder knows how to solve a problem by not writing any code at all. And it’s hard to fathom gaining a sober grasp of computer science fundamentals without the torturous dorm-room hours spent hand-coding, say, Dijkstra’s algorithm or a red-black tree. If you’ve ever tried to learn programming by watching videos and failed, it’s because the only way to internalize it is by typing it out yourself. You can’t dunk a basketball by watching NBA highlight reels.

The jury is still out on whether AI-assisted coding speeds up the job at all; at least one well-publicized study suggests it may be slower. I believe it. But I also believe that for AI to be a true exponent in the equation of productivity, we need a skill I’ll call a kind of mental circuit breaker: the ability to notice when you’ve slipped into mindless autopilot and snap out of it. The key is to use AI just enough to get past an obstacle and then toggle back to exercising your gray matter again. Otherwise, you’ll lose the kernel of understanding behind the task’s purpose.

On optimistic days, I like to think that as certain abilities atrophy, we will adapt and develop new ones, as we’ve always done. But there’s often a creeping pessimism that this time is different. We’ve used machines to take the load off cognition, but for the first time, we are offloading cognition itself to the machine. I don’t know which way things will turn, but I know there has always been a certain hubris to believing that one’s own generation is the last to know how to actually think.

Whatever gains are made, there’s a real sense of loss in all this. In his 2023 New Yorker essay “A Coder Considers the Waning Days of the Craft,” James Somers nailed this feeling after finding himself “wanting to write a eulogy” for coding as “it became possible to achieve many of the same ends without the thinking and without the knowledge.” It has been less than two years since that essay was published, and the sentiments he articulated have only grown more resonant.

For one, I feel less motivated to learn new programming languages for fun. The pleasure of learning new syntax and the cachet of gaining fluency in niche languages like Haskell or Lisp have diminished, now that an AI can spew out code in any language. I wonder whether the motivation to learn a foreign language would erode if auto-translation apps became ubiquitous and flawless.

Software engineers love to complain about debugging, but beneath the grumbling, there was always a quiet pride in sharing war stories and their clever solutions. With AI, will there be room for that kind of shoptalk?

There are two types of software engineers: urban planners and miniaturists. Urban planners are the “big picture” type, more focused on the system operating at scale than with fussing over the fine details of code — in fact, they may rarely write code themselves. Miniaturists bring a horologist’s care for a fine watch to the inner workings of code. This new modality of coding may be a boon for urban planners, but leave the field inhospitable to miniaturists.

I once had the privilege of seeing a great doyen of programming in action. In college, I took a class with Brian W. Kernighan, a living legend credited with making “Hello, world” into a programming tradition and a member of the original Bell Labs team behind Unix. Right before our eyes, he would live-code on a bare-bones terminal, using a spartan code editor called vi — not vim, mind you — to build a parser for a complex syntax tree. Not only did he have no need for modern tools like IDEs, he also replied to email using an email client running in a terminal. There was a certain aesthetic to that.

Before long, programming may be seen as a mix of typing gestures and incantations that once qualified as a craft. Just as we look with awe at the old Bell Labs gang, the unglamorous work of manually debugging concurrency issues or writing web server code from scratch may be looked upon as heroic. Every so often, we might still see the old romantics lingering over each keystroke — an act that’s dignified, masterful, and hopelessly out of time.

3 Comments

Follow topics and authors from this story to see more like this in your personalized homepage feed and to receive email updates.


Share this @internewscast.com