Functional JS: Partial Application and Currying

ยท 404 words ยท 2 minute read

These two techniques can help you simplify the code, even if the paradigm of your project is not functional.

Partial Application ๐Ÿ”—

Through partial application, you can fix some parameters required by a function. The rest can be left to be defined at the time the function is executed.

const square = (x) => Math.pow(x, 2);

In the example, square returns a function that can be executed later without having to pass all the parameters, only the base.

What do functions with partial application offer? A function with partial application can be partially created in a context where we have access to certain variables, which may not be available in the final context where it will be executed.

One of the most common uses is with map. When transforming an object using its map method, we typically do it as follows.

const myArray = [
  { id: "EUR", value: 1 },
  { id: "DOLLAR", value: 2 },
];

const myDropwdownOptions = myArray.map(({ id, value }) => ({
  label: id,
  value,
}));

In the example, we transform an object into another one that meets a specific interface, in this case, the options of a dropdown. This transformation function can be extracted to a pure function.

const myArray = [
  { id: "EUR", value: 1 },
  { id: "DOLLAR", value: 2 },
];

const mapOptions = ({ id, value }) => ({
  label: id,
  value,
});

const myDropwdownOptions = myArray.map(mapOptions);

Let’s consider the case where we are building an internationalized app and we have to translate the labels, assuming that what we have in the object are the translation keys. How could we maintain a pure function and pass additional arguments? As you may have guessed, through partial application.

const myArray = [
  { id: "EUR", value: 1 },
  { id: "DOLLAR", value: 2 },
];

const mapOptions =
  (translate) =>
  ({ id, value }) => ({
    label: translate(id),
    value,
  });

const myDropwdownOptions = myArray.map(mapOptions);

Currying ๐Ÿ”—

Currying would take this technique one step further and convert a function call into a series of calls, each with a single parameter as an argument. It is similar to partial application, but with the restriction that all functions returned in the chain must have exactly one parameter.

function sum(x) {
  return function (y) {
    return x + y;
  };
}

Indeed, these techniques are widely used, and several libraries allow automatic conversion of a function into another with partial application.