Functional programming in JavaScript

Functional programming in JavaScript

What Is Functional Programming?

Functional Programming is a programming paradigm where we write our code as pure functions and avoid side effects.

So functional programming says that a function:

  • should be a pure ( i.e does not have any side-effects )
  • should not mutate its input ( i.e argument )
  • should always take at least one input and should always return an output

So let's see what does the above points mean.

We can say a function is pure when it does not mutate its input and for the same input, it always returns the same output.

Let's see an example:

// pure function
const add = (a, b) => a + b
console.log(add(2,3)) // 5

Now above is a simple add function that takes two numbers and returns the sum of that. Irrespective of how many times this function will be called for the same inputs it will always give you the same output.

Let's see another example that does not follow this:

let a = 2
let b = 3
const add = () => a + b
console.log(add()) // 5

a += 10
console.log(add()) // 15

If you see the above example, it does not take any input and it uses global values a = 2 and b = 3, suppose these values changes over time then the output of the add function won't be the same.

Also as mentioned above a pure function should not mutate ( i.e modify the inputs). Lets see whats that means:

const arrayOfNumbers = [1, 2, 3, 4, 5]

const addTwo = (array) => {
  for (let i = 0; i < array.length; i++) {
    array[i] += 2  // adds two to each array element
  }
  return array
}

console.log(addTwo(arrayOfNumbers)) // [3, 4, 5, 6, 7]
console.log(arrayOfNumbers)  // [3, 4, 5, 6, 7]

In the above example, when addTwo function runs, it mutates the array which is passed as an argument to it. So if we see the console after the function has been called the original array has been updated, which is a side effect. So we should avoid the side effects because there might be cases where arrayOfNumbers is used by some other functions, so their output will also be affected.

The solution for this is, to make a new array, store the result of each iteration in that and return that array.

const arrayOfNumbers = [1, 2, 3, 4, 5]

const addTwo = (array) => {
  const output = []
  for (let i = 0; i < array.length; i++) {
    output.push(array[i] + 2)  
  }
  return output 
}

console.log(addTwo(arrayOfNumbers)) // [3, 4, 5, 6, 7]
console.log(arrayOfNumbers)  // [1, 2, 3, 4, 5]

Higher Order Functions

Functions in javascript are first-class citizens ( i.e the ability to use a function as a value):

  • We can pass a function inside another function.
  • We can return a function from another function.
  • We can assign a function to a variable and properties of other objects.

Let's understand this with an example:

const arrayOfNumbers = [1, 2, 3, 4, 5]

const updateArray = (array, instruction) => {
  const output = []
   for (let i = 0; i < array.length; i++) {
    output.push(instruction(array[i]))  
  }
  return output 
}

const addTwo = (number) => number + 2

console.log(updateArray(arrayOfNumbers, addTwo))  // [ 3, 4, 5, 6, 7 ]

In the above example updateArray takes instruction as a parameter, instruction is a function that takes one argument, does something, and returns the output, in this case, it is addTwo function which adds two to the given input and returns it. So over here updateArray is a higher-order function.

We get several built-in higher-order functions in javascript. map, filter, and reduce are some of them. All these functions iterate through each element of the array and run a function on each of them. These functions used on the array are stored in Array.prototype object and every array have access to that object.

const arrayOfNumbers = [1, 2, 3, 4, 5]

const addTwo = (number) => number + 2
const output = arrayOfNumbers.map(addTwo)

console.log(output)  // [ 3, 4, 5, 6, 7 ]

Advantages of Functional programming:

  • More readable and predictable code.
  • Fewer bugs, as there will be no side effects.
  • Easier to add features.
  • More code reuse.