Humble coding

Kamil Tałanda
3 min readMar 6, 2022

A not long time ago, I wrote a beautiful piece of code. I was very proud of how decoupled it was, how flexible and reactive. I iterated over it a few times while testing the solution in the wild and incorporating reviews from my peers. It felt perfect to have all perfectly unit-tested, even UI-tested. Everything went well until I started seeing some unexpected behaviours. It turned out the app wasn’t prepared to consume my feature as a reactive stream, and sometimes in some circumstances that I previously missed, it started behaving a bit weird. So I have two paths to choose from. On one side, I could have kept fixing the code that uses my beautiful reactive class, or on the other hand, I could have found another less excellent way but does the job in an old-fashioned, imperative way. A few years ago, I would probably stick to my guns and want to show the whole world how good is my solution and how wrong is the code that breaks using it. However, it would likely take me another week to tweak the code, not to mention conversations with other devs that maintain that code every day. Fortunately, now I know the code is not about me but about the product we maintain and the team I work with. So I decided to revert to the reactive approach and go imperatively. It turned out to be a straightforward change that is also decoupled. Of course, there are some tradeoffs, but the code is relatively clean.

The more experience I have in software development, the more I see essentials in our craft. Code is not for the machine but for humans to read, so unless you work in an industry that requires performance at the top level, you should focus more on clarity rather than speed. It is more important for code to be correct rather than fast. No matter how quickly you do something, you waste all the effort if it is wrong. The same goes for the beauty of code. I tried to apply a reactive pattern to the code that was not prepared to consume streams in my example. Great idea if everybody is on board and you have a lot of time for refactoring. Since the code is for humans to read, applying an abstract pattern hiding the complexity, but unfortunately, often also the intentions, could be a mistake. It is much better to take a step back and create a simple solution that works and could be easily understood, even below your ambitions.

The problem is often in taking the step back. It implies admitting to being wrong, and we as humans are not best at doing that. But I firmly believe that this is the way to go if something doesn’t go as expected. Instead of looking for a mistake around in the work of others, I believe it is better to see our actions and think about what we can do to make it better without blaming others. Sometimes it is not a mistake in the way we implement something. It might be the way we approached it. The solution might be great, very reactive, easy to maintain, decoupled, etc. but still don’t fit the context, and at the end of the day, it is better to remove it. No hard feelings.

--

--