Standing on the shoulders of giants

It’s no secret that LLMs have taken tech by storm. I’ve deliberately avoided writing about them due to strong opinions flying around on both ends of the spectrum. Some people swear by it while others condemn it.

Do I think companies spending unfathomable amounts of money on building data centers in locations that displace communities is okay? Absolutely not. Do I believe that the massive uptick in compute around the world has negatively impacted Earth’s environmental issues? Yeah, and it’s really scary.

At the same time, I work in an industry where companies strongly encourage the usage of this technology. I live in a country where health care depends on health insurance that is notoriously hard to secure without full-time employment. So yes, I use LLMs at work, contrary to my own beliefs and feelings.

Now, with that said, what I’m interested in writing about in this post is craft.

Some call this moment in time the industrialization of tech, much like when factories came and completely changed jobs in the past few centuries. I don’t think software is getting industrialized in the same way.

With factories, there were well-documented and well-practiced processes for many industries that were systematized and eventually automated with machines. Once a production process has been distilled into a repeatable formula, automating it and fine-tuning it over time was possible.

Building software never really reached a point where we could capture it in a formula. Software is a melting pot of a ton of things. There are websites, web apps, mobile apps, desktop apps, operating systems, embedded systems, etc., and each of these have their own multitude of sub-categories.

Not only that, but there’s no “right way” of doing things. Big tech builds software differently than small tech because of completely different needs. As software grows, tech debt accumulates which changes scaling approaches. Various development techniques have swelled and waned over the years. They seem to pass by like seasons.

Procedural languages, object-oriented programming, functional programming, content management systems, model-view-controller, model-view-viewmodel, SOLID, REST, monoliths, microservices, test-driven development, A/B testing, dynamic languages, typed languages, relational databases, NoSQL databases, containers, container orchestration, serverless, the list goes on and on and on.

Vibe coders seem to be discovering (the hard way) many aspects of software development that are innately part of the craft. Once code is deployed, it needs to be maintained. Security can’t be an afterthought. Design is complex because humans are complex. Accessibility is vitally important. Nothing is ever “done” because systems keep evolving over time. The evolution is part of the product. (That’s not to say that there aren’t people well-positioned to take on these challenges. There most certainly are.)

Language models do a good job of convincing us that they understand us, but ultimately it’s applied statistics with a lot of data. I’m watching in real-time as people seem to be throwing out things like testing principles and semantics. With or without LLMs, we should still be thinking about the different layers of software development and building resilient systems.

“AI fatigue” is a term I’ve seen used in recent months, and I quite like it. Many find themselves reviewing so much more code than before while manually writing less of it. There’s less flow state. Only locked-in state. That’s exhausting.

I think what I’m trying to say with all of this is that we should continue investing and building on the generations of thought work that precede us. People and systems continually change, and so will software.

We’re standing on the shoulders of giants.