The Case For Expression Reduction

theprivileges

Luiz Lopes

Posted on April 20, 2020

The Case For Expression Reduction

This article was originally posted at wickeddeveloper.com.

As a software developer you will inevitably have to debug some piece of code you wrote months if not years ago, or code from a colleague that is no longer part of your team. As you step through some routine you notice an array of conditional statements with complicated conditional expressions. As you search for the bug in the code you'll end up noticing that you can't hold all of the values in your head. You can no longer remember what a particular value means or what it points to.

I have found that creating boolean variables that hold the value of an expensive or complicated expression makes it easier to read and understand code.

Let's look at a trivial piece of code, written in JavaScript, and see how assigning complex conditions to a variable makes it much easier to understand and read the code. Keep in mind this code is not something you'd use in production, I'm only using this to illustrate the point.

Suppose there is a function that takes an argument called drink and inside of this function we check what type of drink it is and return an emoji of a coffee, tea, or milk.

/* Assume COFFEE, CAFE, LATE, MOCHA, TEA, etc are imported into this module. */

function getDrinkEmoji(drink) {
    if (drink === COFFEE || 
        drink === CAFE || 
        drink === LATE || 
        drink === MOCHA) {
        return 'β˜•';
    } else if (drink === TEA || 
               drink === BLACK_TEA || 
               drink === GREEN_TEA || 
               drink === OOLONG_TEA) {
        return '🍡';
    } else {
        return 'πŸ₯›';
    }
}
Enter fullscreen mode Exit fullscreen mode

Reading through code like that requires you to hold quite a lot in your head.

Now let's look at the same code but having assigned the expression to a variable.

function getDrinkEmoji(drink) {
    const isCoffee = drink === COFFEE || 
                     drink === CAFE || 
                     drink === LATE || 
                     drink === MOCHA;
    const isTea = drink === TEA || 
                  drink === BLACK_TEA || 
                  drink === GREEN_TEA || 
                  drink === OOLONG_TEA;

    if (isCoffee) {
        return 'β˜•';
    } else if (isTea) {
        return '🍡';
    } else {
        return 'πŸ₯›';
    }
}
Enter fullscreen mode Exit fullscreen mode

Here we can more quickly understand what the expressions inside of the if and else if are evaluating to.

πŸ“Œ You may also prefix your variables with words like has, should, was, etc.

This pattern makes a lot of sense when you find yourself evaluating the condition multiple times. When you do it once you can just reference the variable again when you need it.

In this next example, our function receives an array of drinks, we use the Array.some method to test whether the drinks include a coffee or a tea and then return an emoji.

function getDrinksEmoji(drinks) {
    const hasCoffee = drinks.some(drink => drink === COFFEE || 
                                           drink === CAFE || 
                                           drink === LATE || 
                                           drink === MOCHA);
    const hasTea = drinks.some(drink => drink === TEA ||
                                        drink === BLACK_TEA || 
                                        drink === GREEN_TEA || 
                                        drink === OOLONG_TEA);
    const hasCoffeeAndTea = hasCoffee && hasTea;

    if (hasCoffeeAndTea) {
        return 'β˜• + 🍡';
    } else if (hasCoffee) {
        return 'β˜•';
    } else if (hasTea) {
        return '🍡';
    } else {
        return 'πŸ₯›';
    }
}
Enter fullscreen mode Exit fullscreen mode

We had to execute the expensive computation of testing if the drinks include a coffee or tea once, we referenced that expression multiple times in our code without additional performance penalty, and the code is still easy to read and understand.

Conclusion

Conditional statements are an invaluable tools in software development, they provide us with flow control to determine the output of our programs. You'll inevitably run across them when writing and reading code. If you are the author of the code, or reading code that you have control over, do yourself a favor and assign your expensive and complicated condition statements to variables with meaningful names. Doing so will free up space in your head and your code will be much easier to read and understand.

Links


Thanks to Greg Timmerman, and @nicholascloud for reading a previous version of this post. @nicholascloud also gave this pattern a name (expression reduction).

πŸ’– πŸ’ͺ πŸ™… 🚩
theprivileges
Luiz Lopes

Posted on April 20, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related