My thoughts on Software Mistakes and Tradeoffs

Cracking the Code of Software Engineering Challenges

Posted by Łukasz Chrząszcz on Sunday, August 20, 2023

If you’ve watched Star Wars then you know that only a Sith deals in absolutes. If you are a software engineer, you are probably not a Sith at the same time (if you are, let me know in the comments section below 🤔), but do you deal in absolutes? In software engineering, just like it is with being a Jedi, every decision is all about the tradeoff, and not a single decision is either good or bad. You simply cannot choose one option and not pay the price. Are you adopting microservices? Cool, but you will have more maintenance costs. Are you going for reactive programming? Awesome, but you will have to train the team. See? Tradeoffs!

Recently, I had the pleasure to read the book Software Mistakes and Tradeoffs written by Tomasz Lelek and Jon Skeet. The whole book revolves around the concept that no decision is either entirely good or entirely bad. It is an essence of the authors’ many years of experience in making decisions as software engineers. In each chapter, we discover a new problem that we try to solve using different approaches. Each approach comes with several pros and cons, and it’s all about choosing the right fit for your project.

This book is a great read with solutions for all the “holy wars” in your team. For sure, you had some in your team. Do you remember when you had a fierce discussion with your colleagues about introducing functional programming to the project? Maybe you were arguing about using that shiny new library? After reading the book, if I ever take part in similar discussion, I will just suggest reading a chapter from Software Mistakes and Tradeoffs, to set out the basics and know what to check before deciding. Given that, I felt exactly like I would be reading Building Microservices by Sam Newman. It goes through all the aspects of something and gives you the scope of things to consider when making your choices. It makes you know what you do not know.

Let’s explore a few chapters from the book that I particularly loved, so you can get the gist of an idea of what the book is about.

Disclaimer: I had the pleasure of working with Tomasz Lelek (those were the times! 😄) and he gifted me the book, so I could read it and share my thoughts here. Nevertheless, I’m describing my genuine thoughts so do not fear any bias 😄

Oh cool! There is a library for that!

I have heard that the best programmers are the laziest programmer. The first thing we all do is to check if there is a library for anything we would like to do. For many people, it is a no-brainer. For me, it was also the case a few years ago. However, I realized a few times, that the overall maintenance cost of a library I chose is higher than any time savings I got from not writing that piece of code on my own.

The authors of the book also mention that you have to be extra careful when choosing the library. Just like in the well-known comic joke titled “What if programming languages were essays”, it is tempting to just type from essay import * 🥁, but…

  • What about the maturity of this library?
  • What about security?
  • Is this library actively developed?

There are so many things to check before using a library!

Obviously, we should not analyze if Spring is mature enough for our project, as some libraries are widely recognized, and we can safely import them, but we should definitely check if that library with just a few stars on GitHub will not cause more maintenance than it makes sense.

If we already checked that the library is actively developed, it has a lot of stars ⭐ on GitHub, but still does not mean that we can import it and call it a day. We have to learn it and understand its default values. The book shows the example of HTTP clients. In most codebases I have seen, the HTTP client is created and used without any configuration… and it works! Unfortunately, sooner or later, we will see timeout errors or degraded performance, because we did not set proper timeouts. The library worked for us locally, in dev environment, in test environment, and even in production environment, but it might be the case that we were just lucky or the default timeouts were way higher than the actual response times (that means our users are waiting for a late response from a dependant server that might never arrive).

Does it mean that you should not use HTTP clients? Not at all! That means that you should not assume that importing and using a library will be a zero-cost operation, you have to understand its configuration and how it works. Relying on default values is fine, as long as you know that they are there and you made a conscious decision to leave them as they are.

Another thing the authors mention is the testability of the new library. Usually, libraries are already tested thoroughly, nevertheless, you might still want to test your expectations and be sure that the library works the way you think it does. If you would like to do that, you might find that it is not always that easy. This is especially important for complex libraries like reactor, where it is extremely hard to simulate some test cases. Fortunately, there is a library reactor-test that provides you with a set of tools to create any tests you would like for your reactive application. That is something you want to look for in the libraries you are importing into your project. So remember to check how easy it is to test your integration with the library.

Finally, keep in mind that adding a new library as a dependency adds to your project library’s dependencies as well. I was always amazed by resilience4j as it has almost no dependencies, so it was always easy to include it. However, not all libraries are like that. I cannot even count the number of times I got conflicting versions of jackson coming from different libraries. To be honest I thought several times that it will be easier for me to just write the library myself 🤣

The cool thing about this chapter in the book is that it gives you a comprehensive checklist to go through before including a new library in your project. Since I have checklists for all repetitive and error-prone tasks (have you read The Checklist Manifesto?), I just loved it as a summary of the whole chapter. Obviously, now I have that checklist on my checklist list.

What timezone is it on Mars?

I always knew that “time” is like a scary movie for software engineers. I knew that there are different timezones, summertime, leap seconds, etc. but this chapter in Software Mistakes and Tradeoffs gave me true goosebumps. There are a few dozens of pages full of caveats, problems, and edge cases connected to time in computers.

You probably know that the time in software engineering is calculated based on something called epoch, which is an agreed moment in time from which computers start to calculate time. A well-known epoch is the 1st of January 1970 which is also called the UNIX epoch, so any date and time are represented as the number of seconds that elapsed from this epoch. That is something I was taking for granted during my whole career, but little did I know that there are different notions of epoch! Thanks to the book I am reviewing, I learned that in .NET the epoch is 01-01-0001T00:00:00.

Another problem described by the book is connected to calculations on dates. To give you an example what might be a non-trivial problem - what is the result of adding 1 month to the 31st of May 2023?

  • Is it the 1st of July 2023? - which is the result of adding 31 days
  • Is it the 30th of June? - which is the result of adding 30 days
  • It might also be the case that you want to just bump the “month” part of the whole date by 1, but June has only 30 days, so the result would be the 31st of June which does not exist. What should be the result then?

The problem is that different libraries have different implementations and the results might vary. You need to be extra careful with that. The best option is to design comprehensive tests that cover such edge cases.

If you are a science-fiction fan as I am, you will be probably excited by the idea of building Moon 🌔 or Mars 🚀 base. However, the book asks another problematic question - if it is 16:00 20th of August 2023 in Poland, what time it is on Mars? Let’s keep in mind that the day on Mars is not 24 hours long (although it is almost 24 hours), a year is not 365 days. Things start to get tricky, right? I believe that it is just a matter of time when we will need to convert 16:00 20th of August 2023 CEST to the “Central Martian Summer Time” 🤣

Surprisingly, according to the book, there is already a suggestion that open-source libraries for time operations should include logic for other planets than Earth. The funniest quote from the book refers to that effort:

“I hope to have retired by the time it becomes relevant to mainstream software engineering”

A fun fact, is that after reading several problems connected to time I thought “Hey! What about time dilation? If we start to analyze the small differences in Earth’s movement then it makes sense to take into account relativistic effects”… and after moving to the next page there it was - the time dilation problem. You might be thinking that it does not make sense to even think about time dilation, but I was surprised that it is actually important in - for example - GPS systems 🛰️

Overall, I could not stop myself from reading this chapter in one sitting, even though it was late at night. It is a marvelous journey from simple and well-known time problems to time dilation and Mars. Awesome 🤩!

Should you adopt the hottest trend?

The third chapter that got my attention is the one about all those fierce discussions in the team about whether we should use a shiny, brand-new technology that promises to solve all problems in our project. Software engineering obviously moves forward, there are new frameworks and libraries every day (I look at you JS 👀! I am checking days since last javascript framework counter every day!). It often makes sense to adopt some new things, but I believe you agree that we should not chase every novelty.

Authors in this chapter describe the pros and cons of dependency injection frameworks, reactive programming, and functional programming. Especially last two caught my attention, as I remember the story of my team when we decided to use reactive programming in one of the services. We expected a huge volume of traffic, so we decided to try out this “reactive thingy” that promises to easily provide high throughput. Little did we know, that although it was fast and efficient, it was also extremely expensive in terms of maintenance.

If we had a book like the one I am describing, we would probably have read this chapter and tried the conventional paradigm first. Unfortunately, we had not had this book, so we went through the pain and troubles of finding out on our own, that although something looks cool, it might not be that great to spend months swearing 😤, fixing bugs 🪲, learning the hard way 🗒 to finally get rid of the reactive programming.

Do not get me wrong, I am not against reactive programming, I really like the idea. I am just saying that in that particular situation, it was overkill and brought us no actual benefit but added the extra maintenance. I think it is worth reading this chapter and learning to cautiously approach every new technology.

Summary

In the ever-changing landscape of software engineering, the book Software Mistakes and Tradeoffs stands out as a true gem, offering insights that every developer can treasure. With its down-to-earth approach to real-world challenges and its knack for dissecting tough decisions, this book is more than a read — it is a reliable companion for your coding journey. I have read so many books about software engineering, and worked for so many years in the industry, that I thought that almost no book can surprise me. I can name just a few technical books, that were actually revolutionary to me. Such books for me are books that describe concepts, ideas, and good practices that will never go out of date. Software Mistakes and Tradeoffs is one of those books, that go through many topics and describe them from many different angles, analysing the pros and cons of every possible solution.

Is this book for experienced engineers or beginners? I would say both. The book might be tricky for beginners because it is really condensed, so some basic concepts are not explained, and you might feel a little bit lost, but the best part of it is that it will make you know what to read later and even more it gives you something you need the most at this stage of your career - experience. This book is a synthesis of many years of experience. If you are already an experienced software engineer, the book will help you fill the gaps in knowledge (if you had any) and it will help you to understand what to take into account when making a decision in your project. Personally, as an experienced software engineer, I was surprised a few times - who would have thought that you have to think about timezones on Mars?! So, whether you are a rookie trying to navigate the maze of software development or a seasoned pro aiming to refine your decision-making, this book has something for you. Let it be your secret weapon for untangling dilemmas and finding the way forward in a world where every line of code is a step toward progress.

I encourage you to read the book on your own. Some books - just like some meetings - could have been an e-mail, meaning that for some books it would be more beneficial to just read the summary, but here it is not the case. I can describe some key points as I did in this post, but the true value is in the examples and the details in each chapter, so think of this summary as an encouragement to read the book, not to replace reading it. Additionally, I think this book should be looked at as a group of separate chapters, as every chapter is a throughout analysis of the different topics, so probably you will revisit selected chapters once you stumbled upon that particular problem in your work.

Further reading

If you would like to purchase the book, here is the link. You can use the code SMT35 to get 35% discount! 🤩

Photo by Tingey Injury Law Firm on Unsplash


comments powered by Disqus