Why the fudge should I use currying?

🍛

Simon Schwartz
DailyJS
4 min readMay 27, 2019

--

I first learnt about currying 2 years ago. My initial impression was ‘oh, that seems pretty dumb’ and I never used it in any code I wrote for the next two years.

This was because there was a lot of literature on what currying was, but little about when and why you should use it. This blog is about what currying is, but more importantly why you should use it.

In this article I give a short intro into currying and then talk about use cases.

What the heck is currying?

Example of a curried function — a function that takes multiple arguments, one at a time.
  1. A curried function takes multiple arguments, one at a time.
  2. Each time an argument is passed to it, it returns a new function that accepts the next argument. It does this until all arguments have been passed where it then returns the final output.
const curried = arg1 => arg2 => arg3 => { ... };

Now here are some important things to understand.

  • A curried function that has only had some of its arguments passed, is incomplete and called a partial application.
  • Each step in the curried function has access to the closure scope of the function. This means when you pass the second argument, it has access to the previous argument and the current internal state of the curried function.
// when we only pass some of the args, we get a partial application
const partialApplication = curried(1)(2);
// we can finish our curried function by passing remaining args
const finalResult = partialApplication(3);
// this is also the equivalent of
const alsoFinalResult = curried(1)(2)(3);

Why the gadzooks would I ever want to do that?

It’s all about composition.

Currying allows us to create new functions with some pre-defined data in their closure scope. Let’s look at some examples of how we can use this to write some more concise and performant code.

Remove repetition

In this example, we need to write some code that generates a list of URLs.

There are some opportunities to improve the code above by using currying! Notice how we are constantly repeating the baseURL argument. Let’s fix that.

Currying allows us to compose new functions, createSiteURL and createCareersURL. These new functions are pre-populated with the ‘mysite.com’ and ‘mysite-careers.com’ baseURLs in their closure scopes. This means we remove the need to repeatedly declare the same baseURL argument on multiple functions.

Isolate expensive processes

We can use a similar method to above to isolate slow or expensive processes.

In this example we have a function that allows us to filter and order a large table of data. Our large data is a database of parcels our company is currently shipping all over the world. We want to get a list of all parcels for a given country and sort that list by the date each parcel was created.

The above code has the same issues as before of repeating parameters. Also notice how each time we call ausParcelsAsc or asuParcelsDsc we will always filter the large array of global parcel data. This could cause an unnecessary performance bottleneck in our software. For example if we needed to re-sort the list multiple times. Let’s use currying to fix this issue.

Notice above how the expensive filter process on the global parcel data happens only once when we create the partial application sortAusParcelsBy. When we run the partial application sortAusParcelsBy the function already has access to the filtered list in its closure scope. This means we only need to filter our giant list of parcels once, rather than every time we need to sort the list.

What are the bad parts?

With great power comes great responsibility — Batman’s Dad

Here are some things I have learnt from working more with currying.

  1. Currying isn’t widely understood by all developers.
    Developers unfamiliar with the technique will have a harder time working with code that uses currying. It can cause also confusion because the syntax can be harder to read than traditional functions.
  2. It’s easy to abuse
    There is nothing stopping you from currying every function in your codebase. Developers may use currying when there may be simpler composition techniques that would also get the job done.
    Do you need to compose re-usable partial applications?
    Do you need to ensure your functions will only have a single argument?
    If you answered no to both these questions, you may not need currying.

Thanks for reading!

--

--

Simon Schwartz
DailyJS

Developer from Sydney, Australia. Aspiring to communicate complex topics in simple ways. Engineer at Australian Broadcasting Corporation.