Codementor Events

Currying in JS

Published Jul 14, 2019Last updated Jan 09, 2020
Currying in JS

Hello, world!

JavaScript is a multi-paradigm programming language, which means it supports both procedural and functional programming. Functional programming allows you to do fun, almost magical stuff. A case in point: currying. In this post, we’ll try to understand what currying is and how to implement it in a simple manner.

Higher-Order Functions

In order to implement currying, we need to learn about higher-order functions. So what is a HOF?

When we talk about higher-order functions, we mean a function that either takes one or more functions as arguments, or returns a function as its result.

You’ll only find higher-order functions in programming languages that support first-class functions (or treat functions as first-class citizens). This means a language that allows us to store functions in variables, pass them around as parameters in function calls or return them as a result of another function call.

Whew! That sounds complex. Well, it isn’t. Because most probably, you’re already using HOFs in your code. Remember map, filter and reduce? They are higher-order functions.

Let’s make a simple higher-order function.

const doubleFunc = fn => {
  return (...args) => {
    return 2 * fn(...args);
  };
};

So what’s going on over here?

We wrote a function called doubleFunc that takes a function fn as an argument, and returns a new function that takes an arbitrary number of arguments. Upon our providing these arbitrary number of arguments to this function, it then applies fn to them, multiples the result by 2 and returns the result.

We have collected the arbitrary number of arguments into the args array above by using spread/rest (…) operator in ES6. Read more about it in Kyle Simpson’s awesome book here.

const add = (x, y) => x + y;
const doubleAdd = doubleFunc(add);

console.log(doubleAdd(1, 4)); //=> 10

Cool? Cool.

Currying

Now that we understand what a higher-order function is, how can we leverage this knowledge to make a currying utility? Let’s define currying first.

Currying is the process of taking a function with multiple arguments and returning a series of functions that take one argument and eventually resolve to a value.

Okay, that’s a bit hard to wrap your head around. In simple terms, currying is the process of transforming a function that takes multiple arguments into a function that takes lesser arguments by fixing some of the arguments.

Let’s write a couple of increment functions by modifying add.

const add = x => y => x + y;
const inc1 = add(1);
const inc2 = add(2);

inc1(4); //=> 5
inc2(4); //=> 6

Great! By currying our add function, we have made its logic reusable and pulled out 2 functions from it.

That’s fine and all but how can we curry any function? Let’s write a utility for this.

function curry(fn) {
  return function(...args) {
    if (args.length >= fn.length) {
      return fn(...args);
    }

return function(...more) {
      return curry(fn)(...args, ...more);
    };
  };
}

Okay, let’s break it down. We wrote a function called curry that takes a function fn as an argument and returns a n-arity function (a function that takes an arbitrary number of arguments). Now, this function does a couple of things.

  1. If the number of arguments provided to this function is equal to or greater than the number of arguments needed by the function fn, it simply invokes fn with these arguments.
  2. Otherwise, it returns another n-arity function which when provided some more arguments, tries to invoke the curried fn with args and more.

This process keeps on going until the condition in step 1 is satisfied.

If you don’t understand what’s happening here, I encourage you to copy this utility, add loggers to it and use it to curry a simple function of your own.

The above snippet is too verbose. Let’s rewrite it with arrow functions.

const curry = fn => (...args) =>
  args.length >= fn.length ? 
  fn(...args) :
  (...more) => curry(fn)(...args, ...more);

Much cooler! Let’s use this newly found power.

const sort = (ascend, list) => {
  const ascCmp = (a, b) => a > b;
  const dscCmp = (a, b) => a < b;
  return [...list].sort(ascend ? ascCmp : dscCmp);
};

const curriedSort = curry(sort);

const sortAsc = curriedSort(true);

const sortDsc = curriedSort(false);

const data = [9, 99, 29, 42, 45, 57, 13];

sortAsc(data); //=> [9, 13, 29, 42, 45, 57, 99]

sortDsc(data); //=> [99, 57, 45, 42, 29, 13, 9]

By currying sort, we were able to partially apply the function by fixing the value of ascend flag and storing the resulting function, which now only takes a list of numbers, to a separate variable.

Partially applying functions can help us reuse our functions in a cleaner way. We can even pass these partially applied functions around in our application for delayed evaluation down the execution line when the remaining arguments will be available to us.

Higher-order functions are the bread and butter of functional programming, and currying and partially applied functions enable higher-order functions to be used much more effectively and concisely. But HOFs enable a lot more than just currying, things like composition, memoization and transducing, etc.

If you liked this taste of functional programming in JS, you should check out these functional programming libraries: Ramda and lodash/fp.

That’s it for currying, guys. Hope you learned something about this cool technique. If you liked this post, please clap and share. Ciao!

Discover and read more posts from Muhammad Kasim
get started
post commentsBe the first to share your opinion
Show more replies