Why You Should Avoid Conditionals

Deeper insights into what I have learned about good and bad conditionals and how

Johannes Scheiermann
4 min readAug 20, 2020
A man with headphones sits thoughtfully in front of his laptop
Photo by Wes Hicks on Unsplash

One day when a peer software developer came up to me, asking if I wanted to solve a kata, I had no clue what a kata is - at least the name sounded pretty cool and I probably would learn something. So my response was: ‘sure!‘.

The katas task was all about a man called Bob who is not the most eloquent. So in conversations his responses usually are very limited. He answers with:

‘Dude relax!‘ - if he is yelled at
‘Of course.‘ - if he is asked something
‘Calm down, I know what I’m doing!‘ - if someone yells a question
‘Ok, then let’s be silent.‘ - if the other person says nothing
‘Whatever.‘ - otherwise

This kata came along with unit tests, thus my only job would be to implement the Answer method. The task did not seem too difficult, but then my colleague added an unexpected limitation:

‘The solution should avoid any conditional statements.’

The purpose of this constraint was not immediately clear to me but I like challenges, so what?

A man programs on his laptop
Photo by Danial RiCaRoS on Unsplash

No if statements? No switch statements? Is this even possible?

A lot of questions were circling in my overwhelmed brain when my curious self sat down and began to face the challenge. I quickly realized that it was harder than expected and after some frustrations my first thought was: ‘Damn, he tricked me, I need to use the ternary operator‘. Unfortunately it was not allowed either. I was confused and did not know what to do next; what a good time for coffee.

After not being able to solve the problem of avoiding conditionals, I at least wanted to do it with them. So my first solution looked like this:

Even if solving the task using conditionals was not the desired solution, it at least was a quick and straightforward way to get a deeper understanding of the requirements and green unit tests.

Finally, after thinking further and reading something about polymorphism (and drinking more coffee), I came up with the following solution that does not require any use of (self-written) conditionals:

The new solution requires more lines and some boilerplate code for the different Answer classes. However, it is a cleaner and more scalable approach because of the following reasons:

  1. Adding more possible answers to the first solution would inflate the Answer method. Sure it is possible to reduce the code partially by nesting methods, yet there are also other quick-witted reasons.
  2. The Bob class of the first solution depends on changes in the answer texts. This is a sign for bad design as the class only should know the Answer classes and not any implementation details. Whereas the second solution encapsulates these implementation details in appropriate domain types (like YellingAnswer, QuestionAnswer, DefaultAnswer, …). This makes it not only easier to change or extend answers at runtime. Also, the Answer objects become reusable and their behavior is centralized in clear classes without the noisy code of the other Answer types.
  3. Furthermore, the second approach’s code is more understandable because it splits the code into smaller pieces and also provides a declarative and fluent readable code.

Conclusion

I know that under the hood, the First method (line 15) which I used in my solution requires the use of conditionals to check if the passed condition applies to an item of the enumerable. Due to the following reasons, it is nevertheless a good habit to avoid as many conditionals as possible. Even polymorph code requires conditionals on a higher level to determine which behavior is the one to use. We can not keep conditionals completely away from us since the source codes we write will become machine code in the end. It is not just about avoiding conditionals, it is more about understanding that there are good and bad ones.

The bad conditionals are not the ones that evaluate a value. Instead, they are used for side effects that lead to an increased code complexity which makes it more difficult to test and maintain single features.

On the other hand, good conditionals usually evaluate a value. In the example above one of them is responsible for determining which polymorph behavior of several to choose. Most of us are not writing machine code which usually relies on GOTO statements. We usually are programming with higher-level languages that provide a human-readable abstraction from these very technical machine codes. So we should use these abstractions (e.g., the First method in .NET LINQ) to keep our code readable for us and our coworkers.

PS: Last but not least…

I want to note that the concept of coding katas convinced me since katas are a good opportunity to step back from the everyday projects and deep dive into a problem context while concentrating on training a specific skill. In my case, the restriction of conditionals led to a creative process in my mind and it was a really enjoyable experience.

This experience was so enjoyable that it caused me to write my first medium story about it. At this point I thank everybody who read this article to the end. I am looking forward to your feedback and reading about your experiences on this topic!

Have a nice day.
Johannes

--

--

Johannes Scheiermann

A computer science student based in Germany who is coding for a living and pursuing never-ending education