In last week’s post, I mentioned that a *higher-order function* is one way to pass extra arguments to a function in JavaScript. This is closely related to a technique called *currying*, named after Haskell Curry, the noted mathematician and logician. *Currying* is the process of converting a function with multiple parameters into a series of functions, each of which has a single parameter.

## Currying

Perhaps the most common example you’ll find online is a function that adds two numbers together. Before currying, the function has two parameters. It returns the sum of its parameters’ values:

`const add = (a, b) => a + b;`

add(1, 1); // 2

After currying, the function has a single parameter. It returns *another function* with a single parameter. Because the inner function is in the *lexical scope* of the outer function, it has access to the value of the outer function’s parameter (creating a *closure*). The return value of the inner function is the sum of the parameters’ values:

`const add = a => b => a + b;`

add(1)(1); // 2

Arrow function expressions are often used in functional programming because they closely resemble mathematical functions. However, you can certainly create curried functions with traditional function declarations and function expressions:

`function add(a) {`

return function (b) {

return a + b;

};

}

## Partial application

If you’re not used to functional programming, this might seem silly. Why would you convert a function that returns a sum into a function that returns *another function* that returns a sum? The answer is *partial application*. This is when you call a curried function with fewer arguments than its total number of parameters. The benefit of this is that instead of calling the functions all at once (`add(1)(2)`

), you can call them in *steps* to create more specific functions.

For example, you could *partially apply* the `add()`

function to create `increment()`

and `decrement()`

functions:

`const add = a => b => a + b;`

const increment = add(1);

increment(5); // 6

const decrement = add(-1);

decrement(5); // 4

In fact, you could create a function that adds *any number you want:*

`const add = a => b => a + b;`

const add10 = add(10);

add10(20); // 30

const subtract15 = add(-15);

subtract15(65); // 50

**This is the true benefit of currying.** Once a function has been curried, you can *partially apply* it to create more specific functions. This makes a curried function very flexible and composable.

You can still use the function to add two numbers together:

`const add = a => b => a + b;`

add(6)(7); // 13

But you also have the option to *partially apply* it, which makes it more composable.

If you want to use both syntaxes, there are utility functions that enable this. For example, the Lodash library provides a `.curry()`

method. The currying tutorial on JavaScript.info explains how it works.

`const add = _.curry((a, b) => a + b);`

add(6)(7); // 13

add(6, 7); // 13

## A practical example

Adding numbers together is a great way to explain the *theory* of currying and partial application. But how about an example from “the real world,” which is often more messy? My favourite example I’ve found online is that of **isolating expensive processes.** I’ll share the code in verbatim and try to explain it in my own words, but I encourage you to read the original post: Why the fudge should I use currying?

### Before currying

The idea of this example is that we have a database of global parcels, represented by the `allGlobalParcels`

array. This is a very large array with 2,701,201,203 elements. Obviously, filtering the array will be a very expensive process, due to the sheer number of elements. Before currying the `sortParcelsByCountry()`

function, it filters the enormous array *every time we call it.* To quote Rich Harris: as engineers, we should be offended by all that inefficiency!

`// Given a database of global parcels like this...`

const allGlobalParcels = [

{

created: 576424800000,

location: "aus",

properties: {/* ... */},

},

{

created: 1558163267311,

location: "us",

properties: {/* ... */},

},

// ...2701201201 more items

];

const sortParcelsByCountry = (parcels, country, order) => {

// 1. Filter our list to only include parcels from `country`

const countryParcels = parcels.filter(parcel => parcel.location === country);

// 2. Sort the list of parcels by date created

const sortedResult = [...countryParcels].sort((a, b) => {

if (order === "ascending") return a.created - b.created;

// By default return packages by descending order

return b.created - a.created;

});

return sortedResult;

};

const ausParcelsAsc = sortParcelsByCountry(

allGlobalParcels,

"aus",

"ascending"

);

const ausParcelsDsc = sortParcelsByCountry(

allGlobalParcels,

"aus",

"descending"

);

### After currying

To fix this inefficiency, we can *curry* the `sortParcelsByCountry()`

function. The outermost function will have a single parameter: `parcels`

. It will return another function with a single parameter: `country`

. The inner function will sort the `parcels`

by `country`

, then return another function with a single parameter: `order`

. The innermost function will sort the filtered array by `order`

and return it.

By *partially applying* the `sortParcelsByCountry()`

function, we can create another function called `sortAusParcelsBy()`

. This function is specifically for sorting Australian parcels. **The expensive filtering process only happens at this stage, when we partially apply the function.** The result is that we can sort the list of Australian parcels in different ways, without having to keep filtering the gargantuan array.

`// Given a database of global parcels like this...`

const allGlobalParcels = [

{

created: 576424800000,

location: "aus",

properties: {/* ... */},

},

{

created: 1558163267311,

location: "us",

properties: {/* ... */},

},

// ...2701201201 more items

];

const sortParcelsByCountry = parcels => country => {

// 1. Filter our list to only include parcels from `country`

const countryParcels = parcels.filter(parcel => parcel.location === country);

// We now return a function that sorts the parcels by date created

return order => {

// 2. Sort the list of packages by date

const sortedResult = [...countryParcels].sort((a, b) => {

if (order === "ascending") return a.created - b.created;

// By default return packages by descending order

return b.created - a.created;

});

return sortedResult;

};

};

// We create a new function with the filtered list of parcels by country in its closure scope

const sortAusParcelsBy = sortParcelsByCountry(allGlobalParcels)("aus");

const ausParcelsAsc = sortAusParcelsBy("ascending");

const ausParcelsDsc = sortAusParcelsBy("descending");

## Summary

*Currying* is the process of converting a function with multiple parameters into a series of functions, each of which has a single parameter. The benefit of a curried function is that you can *partially apply* it. This is when you call a curried function with fewer arguments than its total number of parameters. The benefit of *partial application* is that instead of calling the series of functions in one go, you can call it in steps to create more specific functions. This helps make your functions more composable.