Javascript: Path to eliminating If/else

I’ve had this personal mantra saying “Avoid if..else..else if statements and use expressions instead” if I can help it. That means I can only use a ternary expression when it comes to some control flow.

const decision = val => (if boolean evaluation with val is true)
? returnMe
: elseReturnMe;

I am now limited to just 2 possible return values or operations. Why would I do this? What is the purpose of this masochistic mantra?

This forces me to rethink my code, and forces me to break up my functions into tiny functions that specialize in very small operations. Decisions that my program will make will only be based on boolean evaluations, or True/False evaluations.

This will make it easier because now I only have to think whether it’s going to be True or False. I think this will also make it easy for other programmers to read through my code. Since it will be comprised of tiny little functions that deal with specific operations and simple decisions.

They made computers with binary. I’m pretty sure I can do this, or so my confidence tells me.

Let’s try it with the Fibonacci sequence. The definition, a series of numbers in which each number ( Fibonacci number ) is the sum of the two preceding numbers. The simplest is the series 1, 1, 2, 3, 5, 8, etc.

First, I’ll implement it with if..else..else if statements

const fibonacci = num => {
if (num === 0) return 0;
else if (num === 1) return 1;
else return fibonacci(num - 1) + fibonacci(num - 2);

I know, the curly braces. We’ll, I’m too lazy to type them out. Deal with it.

In Haskell, it’s very easy without the if..else . It looks like this,

fibonacci :: Integral a => a -> a
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci x = fibonacci(x - 1) + fibonacci(x - 2)

That’s because Haskell has pattern matching, we don’t have that in Javascript. That is a topic for another article, it’s just something to tease your curiosity!

How would I implement this in Javascript without pattern matching and without if..else statements?

Brace yourselves! I’m going to have to break my code down. I would need some functions that will evaluate if it’s zero or one.

// isZero :: Int -> Bool
const isZero = n => n === 0;
// isOne :: Int -> Bool
const isOne = n => n === 1;

Yes, I could combine those functions with a disjunction a.k.a logical or. But I now have a choice to use these functions together or individually.

Next, I need a function that will return zero or one:

// zero :: Int -> Int
const zero = n => isZero(n) ? 0 : n;
// one :: Int -> Int
const one = n => isOne(n) ? 1 : n;

It looks like I’m getting farther away from having a simple decision because I’m writing all these functions. What if I can combine them? Let me make an or function. Pun incoming, a dis-function!

// or :: (a -> b) -> (a -> b) -> a -> b
const or = (f, g) => x =>
f(x) || g(x);

How would I use this? Let me use it with the zero and one functions.

// zeroOrOne :: Int -> Int
const zeroOrOne = or(zero, one);

Let’s see if I can already build the Fibonacci function with this without if..else statements

// fibonacci :: Int -> Int
const fibonacci = n => n === 0 || n === 1
? zeroOrOne(n)
: fibonacci(n - 1) + fibonacci(n - 2);
const result = fibonacci(6);
console.log(result) // 8

It works! but wait… I think I can still refactor my boolean evaluation. I have those little functions above, I think I can combine them with or

// isZeroOrOne :: Int -> Bool
const isZeroOrOne = or(isZero, isOne);


const fibonacci = n => isZeroOrOne(n)
? zeroOrOne(n)
: fibonacci(n - 1) + fibonacci(n - 2);
No actual if..else statements were used in this article.

P.S. I chose the photo above because I thought it relates to recursion.

Show your support

Clapping shows how much you appreciated Ken Aguilar’s story.