Higher-order function

·

3 min read

Higher-order function

A function that takes another function as an argument or returns a function as its results are known as a higher-order function.

let's take an example.

function x(){
console.log("Hi");

function y(x){
x();
}

Suppose, I have an array of numbers. I want to have a square, cube and quadrable of the same numbers. I can write functions for getting squares, cubes and quadrable individually.

const numbers = [1,2,3,4]

const calculateSquare = (num) => {
    const output = []
    for(let i = 0; i< num.length; i++){
        output.push(num[i] * num[i])
    }
    return output
}

const calculateCube = (num) => {
    const output = []
    for(let i = 0; i< num.length; i++){
        output.push(num[i] * num[i] * num[i])
    }
    return output
}

const calculateQuadrable = (num) => {
    const output = []
    for(let i = 0; i< num.length; i++){
        output.push(num[i] * num[i] * num[i] * num[i])
    }
    return output
}

const squares = calculateSquare(numbers)
const cubes = calculateCube(numbers)
const quadrables = calculateQuadrable(numbers)

console.log(squares) // [ 1, 4, 9, 16 ]
console.log(cubes)  // [ 1, 8, 27, 64 ]
console.log(quadrables)  // [ 1, 16, 81, 256 ]

So, What do you notice here? There is no any mistake in this code. But, still, this code is so repetitive. We are writing the same function structure again and again. There is a principle in javascript called DRY (Don't Repeat Yourself).

Almost, 90% code is the same, only the difference here is in the logical part. The formula for square, cube and quadrable contains major changes here.

Can we just abstract this logic and store it in another code? Yes, the best approach to do this is by writing another function. This function will take an input, perform the logic on it and return it as an output.

const square = (num) => {
return num * num;
}

const cube = (num) => {
return num * num * num;
}

const quadrable = (num) => {
return num * num * num * num;
}

Now, let's make a generic calculate function.

const calculate = (num, logic) => {
const output = [];
for(let i = 0; i < num.length ; i++){
    output.push(logic(num[i])
}
return output;
}

Here, calculate function is taking another function as an argument, So, calculate function is a Higher-order function now.

const squares = calculate(numbers,square)
const cubes = calculate(numbers, cube)
const quadrables = calculate(numbers,quadrable)

console.log(squares) // [ 1, 4, 9, 16 ]
console.log(cubes) // [ 1, 8, 27, 64 ]
console.log(quadrables) // [ 1, 16, 81, 256 ]

Now, the magical thing here is, calculate function seems similar to the map() function. map() is a higher-order function that works on an array, applies the logic and returns a new array.

console.log(squares)  // [ 1, 4, 9, 16 ]
console.log(numbers.map(square))  // [ 1, 4, 9, 16 ]

so, in the above code, map() is a higher-order function given by Javascript to us, whereas calculate is also a higher-order function written by us which works the same as a map().

Now, we might think, map() is directly applied to an array using the dot ( . ) operator, but we are passing an array as an argument in our calculate function. Let's make it exactly similar to the map() function.