Currying

Functional programming is almost as popular as object-oriented programming. Many concepts from object-oriented programming have entered programming in general so deeply that sometimes we no longer even notice where a given approach comes from. Functional programming also has its interesting concepts, and currying is one of them. In this article I use examples to show how currying works and what problems it can help us solve.

Matryoshka dolls

From this article you will learn:

  • What is currying?
  • How can currying help solve the problem of too many arguments in a function?
  • Where can we encounter currying in React projects?
  • How does conversion to a primitive value work in JavaScript?

Have you ever run into the problem of a function having too many arguments? Functions like that become hard to read, and their complexity can make the code creation process itself more difficult, which in turn leads to bugs. In many guides and lists of good practices, we very often see the recommendation that functions should not accept more than one or two arguments.

Today I would like to touch on an interesting topic related to functional programming, namely currying. Currying is often described as expanding a function. It gives us a way to expand functions flexibly while keeping the number of passed arguments as small as possible.

One Function, Many Arguments

The simplest and most common example where currying might be useful is a function that sums numbers.

js
function sum (a, b, c) {
	return a + b + c;
}

Notice that a function prepared this way is not very flexible and must always receive three arguments. Otherwise, it will return an error or an incorrect result.

js
sum(1); // NaN
sum(1, 2, 3, 4); // 6

Of course, we can write this function in such a way that the number of arguments does not matter and the function still returns a correct result, for example:

js
function sum(...args) {
	return args.reduce((acc, curr) => acc + curr, 0); 
}

sum(1); // 1
sum(1, 2, 3, 4); // 10

Is this solution fine? In a sense, yes, but at some point a large number of arguments can make our code much less readable.

One Function, One Argument

The assumptions behind currying are very simple: a function accepts the minimum number of arguments and is flexible enough that subsequent calls let us obtain the correct result. Calling such a function could look like this:

js
sum(1)(2)(3)(4); // 10

In the example above, I can pass subsequent arguments to the sum function by calling it again and again. What happens underneath? The sum function returns an intermediate function that accepts one argument and that we can call again. According to the definition, currying is the transformation of one function into a sequence of functions to which we pass one argument at a time. So let us write a summing function that accepts one argument and returns a new function that increases the passed number on the next call.

js
function sum(value) {
	function add(n) {
		value += n;
		return add;
	}
	return add;
}

The example above illustrates our sum function returning the inner add function. The sum function accepts one argument, just like the inner function does. At every level of our function we of course return the inner function, because it is responsible for our calculations. At this stage our code still does not work correctly. Calling the sum method will return a function, not its result.

To return the value from our calculations, we can add an internal getValue method. This is perfectly valid, because in JavaScript everything is an object, including a function.

js
function sum(value) {
	function add(n) {
		value += n;
		return add;
	}

	add.getValue = () => value;

	return add;
}

sum(1)(3)(5); // f add(...)
sum(1)(3)(5).getValue(); // 9

As we can see in the example, we achieved the intended effect, but retrieving the value requires an additional call. So the question appears: can we skip the last step so that the final call immediately returns the final value?

Converting to a Primitive Value

JavaScript has a built-in valueOf method, which is called automatically to convert an object to a primitive value. It is worth noting that conversion also uses another built-in method, toString. With this knowledge, we can safely assume that overriding both methods will let us change the value that is ultimately returned. What could that look like?

js
function sum(value) {
	function add(n) {
		value += n;
		return add;
	}

	add.valueOf = () => value;
	add.toString = () => '' + value;

	return add;
}

sum(2); // 2
sum(2)(12)(1); // 15

The valueOf method is called by the JavaScript interpreter, so there is no need for us to call it ourselves. Remember that a function overridden this way should not accept any arguments.

Summary

We achieved our goal. The examples above illustrate how currying can be used. So the question is: is it worth it? It seems to me that using this technique lets us make our functions more flexible and increase the readability of our code. There are plenty of examples of currying in everyday work. It is enough to look, for example, at React Redux. The connect method is a good example of applying the principles described above:

js
export default connect(mapStateToProps)(Component);

Sources

Share this article:

Comments (0)

    No one has posted anything yet, but that means.... you may be the first.

You may be interested in

If this article interested you, check out other materials related to it thematically. Below you will find articles and podcast episodes authored by me, as well as books I recommend that expand on this topic.

Optimizing with Memoization by jarmoluk
Article
2026-06-14

Optimizing with Memoization

Cache is tempting because it sounds like a quick answer to unoptimized code. But remembering the result is only the beginning. You still need to know what the key is, when the result becomes invalid, and whether you might return data to the wrong user. That is what memoization is about.

Read more
NextJS i co dalej by Mateusz Jabłoński
Podcast
01 June 2023

NextJS i co dalej

NextJS wprowadził React'a na nowe ścieżki. Śmiało można powiedzieć, że twórcy Next'a zmieniają frontend. O tym rozmawiamy w piątym odcinku podcastu Piwnica IT.

Posłuchaj
React portals by Thomas Piekunka
Article
2022-10-14

Through Portals in React

Interplanetary travel is not exactly available or popular yet. Technically speaking, we can run into similar difficulties when travelling between different DOM structures in SPA applications. Today, let us look at how React solves this problem.

Read more

Zapisz się do newslettera

Bądź na bieżąco z nowymi materiałami, ćwiczeniami i ciekawostkami ze świata IT. Dołącz do mnie.