Currying in JavaScript Explained With Examples

Currying in JavaScript is a process that allows you to transform a function with multiple arguments into a sequence of nesting functions.

Written by Suprabha
Published on Jan. 25, 2023
Image: Shutterstock / Built In
Image: Shutterstock / Built In
Brand Studio Logo

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

In other words, instead of a function taking all arguments at one time, it takes the first one and returns a new function, which takes the second one and returns a new function, which takes the third one, and so on, until all arguments have been fulfilled.

What Is Currying in JavaScript?

Currying in JavaScript transforms a function with multiple arguments into a nested series of functions, each taking a single argument. Currying helps you avoid passing the same variable multiple times, and it helps you create a higher order function.

That is, when we turn a function call sum(1,2,3) into sum(1)(2)(3)

The number of arguments a function takes is also called arity.

function sum(a, b) {
    // do something
}
function _sum(a, b, c) {
    // do something
}

The function sum takes two arguments (two-arity function) and _sum takes three arguments (three-arity function).

Curried functions are constructed by chaining closures and by defining and immediately returning their inner functions simultaneously.

 

Why Is Currying in JavaScript Useful?

  1. Currying helps you avoid passing the same variable again and again.
  2. It helps to create a higher order function.

Currying transforms a function with multiple arguments into a sequence/series of functions, each taking a single argument.

For example:

function sum(a, b, c) {
    return a + b + c;
}
sum(1,2,3); // 6

As you can see, this is a function with full arguments. Let’s create a curried version of the function and see how we would call the same function (and get the same result) in a series of calls:

function sum(a) {
    return (b) => {
        return (c) => {
            return a + b + c
        }
    }
}
console.log(sum(1)(2)(3)) // 6

We could even separate this sum(1)(2)(3) to understand it better:

const sum1 = sum(1);
const sum2 = sum1(2);
const result = sum2(3);
console.log(result); // 6
A tutorial on how to curry functions in JavaScript. | Video: Dave Gray

More on JavaScript: What Are JavaScript Design Patterns?

 

How Does Currying in JavaScript Work?

Let’s look at how currying works. We passed 1 to the sum function:

let sum1 = sum(1);

It returns the function:

return (b) => {
        return (c) => {
            return a + b + c
        }
}

Now, sum1 holds the above function definition, which takes an argument b.

We called the sum1 function, passing in 2:

let sum2 = sum1(2);

The sum1 will return the third function:

return (c) => {
            return a + b + c
}

The returned function is now stored in the sum2 variable.

sum2 will be:

sum2 = (c) => {
            return a + b + c
}

When sum2 is called with 3 as the parameter const result = sum2(3);, it does the calculation with the previously passed in parameters: a = 1, b = 2 and returns 6.

console.log(result); // 6

The last function only accepts the c variable, but it will perform the operation with other variables whose enclosing function scope has long since returned. It works nonetheless because of Closure.

More on JavaScript: 8 Common JavaScript Data Structures

 

Currying vs. Partial Application in JavaScript

Some might start to think that the number of nested functions a curried function has depends on the number of arguments it receives. Yes, that makes it a curry.

Let’s take same sum example:

function sum(a) {
    return (b, c) => {
        return a * b * c
    }
}

It can be called like this:

let x = sum(10);
x(3,12);
x(20,12);
x(20,13);
// OR
sum(10)(3,12);
sum(10)(20,12);
sum(10)(20,13);

The above function expects three arguments and has two nested functions, unlike our previous version, which expected three arguments and had three nesting functions.

This version isn’t a curry. We just did a partial application of the sum function.

Currying and partial application are related because of closure, but they are different concepts.

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

function sum1(x, y, z) {
    return sum2(x,y,z)
}
// to
function sum1(x) {
    return (y,z) => {
        return sum2(x,y,z)
    }
}

For currying, it would look like this:

function sum1(x) {
    return (y) = > {
        return (z) = > {
            return sum2(x,y,z)
        }
    }
}

Currying creates nesting functions according to the number of the arguments of the function. Each function receives an argument. If there is no argument, there is no currying.

Here’s how you can develop a function that takes a function and returns a curried function:

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

The above function accepts a function (fn) that we want to curry and a variable number of parameters(…args). The rest operator is used to gather the number of parameters after fn into …args.

Next, we return a function that also collects the rest of the parameters as …_args. This function invokes the original function fn passing in …args and …_args through the use of the spread operator as parameters. Then, the value is returned to the user.

Now, we can use the above function to create a curry function.

function sum(a,b,c) {
    return a + b + c
}
let add = currying(sum,10);
add(20,90); // 120
add(70,60); // 140

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

Explore Job Matches.