Programming is dead. Long live programming
2022 update: I didn’t post this when I wrote it originally, mostly because I was scared of sharing such “daring” thoughts. I find it comforting that others, braver than me, have expressed similar feelings over the years.
I have a done a lot of thinking lately about software development, what it means to me and ultimately whether I still enjoy it. To me, being able to program has always meant being able to solve problems or automate tedious tasks, either to free up my time or someone else’s. Ultimately deliver value to whoever is going to use the end product, be it another developer or the final user. Another aspect that I always considered a plus is continuos learning, meaning that our discipline is always evolving and there is always something new that you can apply to your daily practice.
Except that I don’t find it to be true anymore. Somewhere along the line it has become more and more about busywork, ever changing libraries and constant updates and breaking apis. I have to admit I’m a bit biased towards web development, although I also follow closely what happens in game development, and while there are obvious differences I think both disciplines suffer from the same issues.
One could argue that the increase in complexity of problems to solve has lead to an increase in requirements on the software side, which demanded more complex tools. Alas, it doesn’t. Aside from changes in esthetics, most websites work exactly as they did ten years ago. You browse web pages, you fill forms and get some data back. Of course what happens behind the scenes is much more intricated than that, given that a single click could touch 1000s of servers (think Google or Amazon scale), but at the same time, not everyone needs that complexity, or at least not immediately. So I cringe when I see new frameworks or package managers that should help you work faster download or depend upon dozens of other packages. I miss the days when jQuery was (almost) all you needed to create a pleasant experience for your users.
I realise that code reuse is a good thing, but with the current speed of development it’s much more likely that one of those dependecies will break during an update. When you get burnt once or twice, you will stop upgrading your dependecies, or, even worse, the whole framework. This outcome not only defeats the purpose of code reuse, but it also leaves developers exposed to security issues in older versions and forces maintainers to fix bugs in multiple versions of their software.
So the burning question is: do we really need all these updates and new versions? Are we really making someone else’s life better? I bet the answer is no. I have a few hypothesis as to why software development is in this sad state of affairs. In the early days of software development it was the case that software cycles would be really long (an for certain types of software that is still the case), leaving users with bugs and missing functionality for extended periods of time. As technology evolved and software release cycles became shorter, users could benefit from more frequent updates, which meant more stable and functional sofware. This transition towards a more agile approach was welcomed and embraced by almost everyone, but at the same time the “release early, release often” mantra became somewhat of a curse. While it’s true that waiting to write the perfect system can lead to paralisis and dead projects or companies, the emphasis has shifted too much towards barely decent. Developers feel liberated by being able to release a new versions of their product multiple times a day, thanks to practices like TDD and CI. While this is a great improvement, especially when security or performance issues are involved, I do wonder whether chasing change is more of an addiction rather than a necessity.
I believe this attitue originated from young companies with a strong engineering culture. By sharing their technical feats and because of their success with users and inverstors, they lead us to believe that this is what matters and what you should puruse as a developer. There can be such a thing as too many people working on the same product, and when that happens it’s likely that some issues falls throught the cracks of an over-engineered system and because of that you need extra fail-safes in place to keep your software operational. The argument is that this is the right way to do things, but I beg to differ. I do agree that having the option to use a good library that saves you reinventing the wheel everytime you start a new project is great, but at the same time you should be wary of being too dependent on it, as it might change its interface, forcing you to either update your existing projects (and is this the best way to spend your time?) or keep working with an outdated version that won’t be maintained any longer. There are obviously exceptions to this, namely some of the libraries that have been around for a while. Again jQuery comes to mind, so when choosing a library it might be better to rely on the true and tested rather than the latest kid on the block - still keep an eye on it though, you never know.
The scale at which these companies operate is unlikely to match that of most other companies, so you can still deliver a great product without all that complexity. Granted, once you do scale you will likely apply some of the same principles, but at the same time just because you can do something, it doesn’t mean you have to. Which brings me to the next point. How many times I mentioned the end users in the previous paragraphs? None. Although most changes are justified as improvements “for the users”, they usually have more benefits for the company (i.e. less busy servers) or their true customers (the advertisers). Even companies that once stood out for their user experience have fallen in the trap of updates for their own sake. Finally, when you employ hundreds or thousands of engineers, it would seem suspicious if you weren’t deploying multiple times a day. Or if you didn’t have this overly-complex systems in places.
Finally, and I might speak just for myself, most of the developers not working for these companies might feel the urge to follow the same practices or otherwise feel less competent or succesfull. After chasing “best practices” for the past few years, I came to the realisation that, while you should be aware of them, the solution to your problem is probably much simpler. I’d rather rewrite the same functionality available elsewhere if it saves me the headache of dealing with yet another library, and in the process you might learn something that you wouldn’t have otherwise. It also gives you full knowledge of that piece of code in case you need to modify it later on. You can always introduce a library later, if you architect your application right. So for me being a happy developer means stop chasing all the latest trends and focusing on delivering real value to my users, whoever they may be. I realise that thinking in these terms might sound like eresy, and indeed when I first had this thoughts I dismissed them as nonsense. But as time went on I realised I wasn’t getting any happier and most of my development time was just busywork. It’s a scary thought, especially if you have been at it for a while and you come to the conclusion you might have wasted a significant portion of your working time. But, as they say, insanity is doing the same thing expecting different outcomes. It’s never too late.
But… but… what about all these job ads that require you to be a “rockstar (or a ninja, or a guru) developer” in X, Y and Z? Well, I don’t agree with most job requirements anyway, as they impose silly restrictions on the technology you should know when what really matters is your ability to think and learn, analyse problems and work in a team. Having said that, some people thrive being more specialised, in which case you should go ahead and dive deep in that particular language or framework. Be careful what you choose though, because as technology changes faster and faster, being familiar with fundamental concepts rather than implementations will always be more beneficial.