CS Basics: How to refactor a boolean expression
Tags: computerscience, javascript
Published: 2019-09-25 16:20:43

# Intro to series
Computer Science sounds so boring, so academic, that sometimes it's hard to know if there's even any useful knowledge for our jobs building actual software.

Of course, I'm half joking. Computer Science is very important to understand what's going on in a computer but I understand it doesn't sound as attractive as learning a specific technology that's in demand in the industry.

With this series of posts, I'll try to extract from those long boring books a few things we can start applying right away and I hope you'll find useful.

I'll always start with the immediate practical part and then I'll explain a bit more about the underlying reasons and terminology.

Let's start today with some boolean expressions.

# Why is it useful to refactor a boolean expression?
It has happened to me many times that, when refactoring a condition, I had to change it to create a method that makes sense in the class. Let's show an simple example.

Imagine we have the following class (in Javascript, but can be applied to almost any language):

```jsx
class Person {
  constructor(name, active, email = null) {
    this.name = name;
    this.active = active;
    this.email = email;
  }

  hasEmail() {
    return this.email !== null;
  }

  isActive() {
    return this.active;
  }

  sendEmail() {
    if (!this.isActive() || !this.hasEmail()) {
      return false;
    }
    // ... send email ...
  }
}
```

At some point we realize that it might be easier to have an internal method that can tell us if the user can receive emails. According to the code that'd mean that it's an active user and has an email set.

We could do this:
```jsx
  canReceiveEmail() {
    return ; // What do we return here? 🤔
  }

  sendEmail() {
    if (!this.canReceiveEmail()) {
      return false;
    }
    // ...
  }
```

As you can see the _sendEmail_ method is more readable now, **but what should we put in the _canReceiveEmail()_ method**?

I'll let you think for a second...🙂

🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔

🤔🤔🤔🤔🤔🤔🤔🤨🐶🤨🤔🤔🤔🤔🤔🤔🤔🤔

🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔

**Did you figure it out?**

What we need is the opposite value of the condition we had:

```jsx
!this.isActive() || !this.hasEmail();
```

The negation of that expression would be:

```jsx
this.isActive() && this.hasEmail();
```

I think intuitively we can understand that if what we were looking for is that:

- The user is not active _OR_ doesn't have email;

The opposite would be that:

- The user is active _AND_ has email.


So the final class would look like this:

```jsx
class Person {
  constructor(name, active, email = null) {
    this.name = name;
    this.active = active;
    this.email = email;
  }

  hasEmail() {
    return this.email !== null;
  }

  isActive() {
    return this.active;
  }

  canReceiveEmail() {
    return this.isActive() && this.hasEmail();
  }

  sendEmail() {
    if (!this.canReceiveEmail()) { // Notice negation of the method with !
      return false;
    }
    // ... send email ...
  }
}
```
<p class="link-code">
 <span class="link-code"><a target="_blank" href="https://jsbin.com/lusafuv/edit?js,console">(see in JSbin)</a></span>
</p>

We could also have created the negative version _cannotReceiveEmail_ but I prefer to use "positive" method names since they tend to be more useful in other places of the code. Nevertheless, If we had done that the result would have been:

 ```jsx
cannotReceiveEmail() {
  return !(this.isActive() && this.hasEmail());
}

sendEmail() {
  if (this.cannotReceiveEmail()) {
    return false;
  }
  // ... send email ...
}
 ```

# Computer Science behind solution
What you just saw wasn't discovered recently, the mathematician who formulated this solution, Augustus De Morgan, died in 1871.

This rule, along with another one we'll see in a bit, are called "De Morgan's Laws". They're part of a bigger field in Mathematics and studied in any computer science course, called Boolean Algebra.

The other rule is as follows. If we have this expression:

```jsx
const willDieSoon = !this.isYoung && !this.worksOut
```

It's equivalent to:

```jsx
const willDieSoon = !(this.isYoung || this.worksOut)
```

If you didn't get this one, think about what would happen in all the potential conditions:

Consider _isYoung_ is true/false and _worksOut_ is true/false. What would be the result of the expression? Wouldn't that be the same that in the first case?

To truly understand this, it's often useful to create a small table of possibilities. The last column represents: _willDieSoon_.

| _isYoung_     | _worksOut_    | _isYoung OR worksOut_  |  _!(isYoung OR worksOut)_  |
| ------------- |:--------| --------| -----|
| false         | false        | false |true |
| true          | false        | true |false |
| false         | true         | true |false |
| true          | true         | true |false |

The same table can be applied to the first expression:

| _isYoung_     | _worksOut_    |  _!isYoung AND !worksOut_  |
| ------------- |:--------|-----|
| false         | false         |true |
| true          | false         |false |
| false         | true          |false |
| true          | true          |false |


## The Morgan's Laws

So the two rules, written in a formal manner, would be:

![De Morgan's Laws](https://josemdev.com/images/morgan_laws.png "De Morgan's Laws")

This image is from Wikipedia since I'm not sure how to add math symbols in dev.to 😞.

So in Javascript, we could say this is:

```jsx
!(P || Q) == !P && !Q

!(P && Q) == !P || !Q
```

We've used the second one to refactor our code.

We started with the _!P || !Q_ and ended with _!(P && Q)_. Let's review it now:

```jsx
// we started with this condition to check before sending the email:
!this.isActive() || !this.hasEmail()

// Then, we moved the logic to canReceiveEmail()
this.isActive() && this.hasEmail()

// And used the negation of that:
!this.isActive() || !this.hasEmail() == !(this.canReceiveEmail())

// Which is:
!this.isActive() || !this.hasEmail() == !(this.isActive() && this.hasEmail());

// So:
!P || !Q == !(P && B)
```

## Other Boolean Algebra Laws
If you didn't know about this boolean algebra laws specifically, don't worry! You're probably applying others like:


![Commutativity](https://josemdev.com/images/commutativity.png "Commutativity")

Those mean that:

```jsx
(weAreInChrome() || weAreInFirefox()) === (weAreInFirefox() || weAreInChrome())

(isRaining() && isCloudy()) === (isCloudy() && isRaining())
```

So, intuitively perhaps, you know that the boolean conditions with two values can be switched in order and the result is the same (🤓🗯️ _that's commutativity!_).

There are [many others boolean laws](https://en.wikipedia.org/wiki/Boolean_algebra#Laws) that are useful so I might do a second part of boolean logic later in the series with the ones that are not so intuitive.

Did you find this one useful? Let me know [on Twitter](https://twitter.com/jmgilgado) please! 👋 🙂

## References
- [Boolean Algebra](https://en.wikipedia.org/wiki/Boolean_algebra)
- [De Morgan's laws](https://en.wikipedia.org/wiki/De_Morgan%27s_laws)