What is Function Currying (and why you should care)

Currying, despite the name, has nothing to do with delectable Indian food.  

Instead, it's a way to compose functions that enable you to embrace a more functional programming style.

Imagine that you have a block of code like this:

const people = [
	{
    	firstName: "John",
        email: "johnsmith@gmail.com"
    },
    {
    	firstName: "Mark",
        email: "justmark@gmail.com"
    },
];

In a real world application, maybe you want to gather the emails from an array of people.  

const getEmails = people => {
	const emails = people.map(person => person.email);
	return emails;
}
// ["johnsmith@gmail.com", "justmark@gmail.com"]
Mapping without currying

Mapping over objects like this is perfectly valid.  But let's say we are looking for a more reusable solution.  

const getProperty = array => 
	desiredProperty => {
		return array.map(item => item[desiredProperty])
    }
    
const emails = getProperty(people)("email");
// ["johnsmith@gmail.com", "justmark@gmail.com"]
Mapping with currying

What's happening here?  The getProperty function takes an array as an argument. But unlike our getEmails function, it doesn't return a list of strings.  Instead, it returns another function!  

This anonymous function takes a parameter called desiredProperty, and then maps over the array that it still has access to, since it was passed into its parent.  The weird double parentheses call pattern is because two functions are being called in one line of code (first the getProperty function, then its anonymous child that accepts the desiredProperty parameter).  This process of chaining functions together is called currying.

Why is this useful?  The best answer is that it allows for highly composable functions.  

const getPeopleProperty = getProperty(people);

const getPeopleNames = getProperty(people)("firstName");
// ["John", "Mark"]

Because getProperty just returns another function, we can use it to create helper functions very easily.  Currying allows for you to reuse your own code in different ways, and allows your code to be very expressive.

Although you can certainly curry functions manually, there are certainly many popular libraries that will allow you to do this even more succinctly.  

import { curry } from 'lodash';

const getProperty = (array, desiredProperty) => {
	const list = array.map(item => item[desiredProperty]);
	return list;
}

const curriedGetProperty = curry(getProperty);

curriedGetProperty(people, "firstName");
// ["John", "Mark"]
Instant curry

Although currying certainly feels weird and unintuitive at first, it is a powerful tool to have in your mental toolbox, and very useful in understanding other people's code.

Happy currying!  

Subscribe to joshuaa.dev

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe