Currying in JavaScript

Currying is a process in functional programming in which we can transform a function with multiple arguments into a sequence of nesting functions. It returns a new function that expects the next argument inline.

NB:The number of arguments a function takes is also called arity.
For example,

function multiply(a, b) {
    // do sth
}
function _multiply(a, b, c) {
    // do sth
}

function multiply takes two arguments (2-arity function) and _multiply takes three arguments (3-arity function).

So,Currying break down a function that takes multiple arguments into a series of functions that each take only one argument.

Here's an example in JavaScript:

function  multiply(x,y,z) {
  return x*y*z;
}

This is a function that takes three arguments, x, y and z and returns their product.

multiply(1,2,3); // 6

We will now curry this function:

function multiply(x) {
    return (y) => {
        return (z) => {
            return x * y * z
        }
    }
}
console.log(multiply(1)(2)(3)) // 6

Now,we turn a function call multipy(1,2,3) into multipy(1)(2)(3)

To better understand this multiply(1)(2)(3), we may divide it into three parts:

const multi1 = multiply(1);
const multi2 = multi1(2);
const result = multi2(3);
console.log(result); // 6

Now,let's get to know how it works.We passed 1 to the multiply function:

let multi1 = multiply(1);

It returns the function:

return (y) => {
        return (z) => {
            return x * y * z
        }
    }

Now, multi1 holds the above function definition which takes an argument y.
We called the multi1 function, passing in 2:

let multi2 = multi1(2);

The multi1 will return the third function:

return (z) => {
            return x * y * z
        }

The returned function is now stored in multi2 variable.
multi2 will essentially be:

multi2 = (z) => {
            return x * y * z
        }

When multi2 is called with 3 as the parameter,

const result = multi2(3);

It does the computation using the parameters that were previously provided in: x = 1, y = 2, and returns 6.

console.log(result); // 6

The last function only accepts z variable but will perform the operation with other variables whose enclosing function scope has long since returned. Because of Closure, it still functions🔥.

Currying & Partial application 🤔

Some may now believe that the number of nested functions a curried function has is proportional to the number of arguments it receives. That qualifies it as a curry.

Let's take same multiply example:

function multiply(x) {
    return (y) => {
        return (z) => {
            return x * y * z
        }
    }
}

It can be called like this:

let a = multiply(10);
a(3,12);
a(20,12);
a(20,13);

// OR

multiply(10)(3,12);
multiply(10)(20,12);
multiply(10)(20,13);

In contrast to our previous version, which had three arguments and three nesting functions, the above function takes three arguments and contains two nested functions.

This isn't a curry in the traditional sense. We've only used the multiply function in a limited way.

Currying and Partial Application are related (because of closure), but they are of different concepts.

Partial application transforms a function into another function with smaller arity.

function multiply1(x, y, z) {
    return multiply2(x,y,z)
}

// to

function multiply1(x) {
    return (y,z) => {
        return mulitply2(x,y,z)
    }
}

For Currying, it would be like this:

function multiply1(x) {
    return (y) = > {
        return (z) = > {
            return multiply2(x,y,z)
        }
    }
}

Currying generates nested functions based on the number of arguments passed into the function. Each function is given a parameter. There is no currying if there is no argument.

To create a function that accepts a function and returns a curried function, follow these steps:

function currying(fn, ...args) {
    return (..._arg) => {
        return fn(...args, ..._arg);
    }
}

The above function takes a function (fn) and a variable number of parameters (...args) to curry. After fn, the rest operator is used to collect the number of parameters into...args.

Then, as... args, we return a function that additionally collects the remaining parameters. This function uses the spread operator to call the original function fn, giving in...args and... args as parameters, and then returns the value to the user.

The above code may now be used to build a curry function.

function multiply(x,y,z) {
    return x * y * z
}

let multi = currying(multiply,10);
multi(2,3); // 60
multi(1,4); // 40

Closure makes currying possible in JavaScript. I hope you have learned something new about currying!

If you've reached this point, thank you very much. I hope that this tutorial has been helpful for you and I'll see you all in the next.

If you like my work, please consider
Buy me a coffee
so that I can bring more projects, more articles for you

If you want to learn more about Web Development don't forget to to follow me on Youtube!

19