How to Make Currying more Readable
By: Cristian Salcescu
Tags: Development, Programming, Functional Programming, Front End Development, JavaScript

Currying is a functional programming technique for transformation a function with n parameters into a series of n functions each expecting one argument.

I am exploring for some time the options for enabling currying on functions in JavaScript and how to make it easier to read. Next, we will look at what I found and you may give your thoughts on which looks better.

Let’s look at how currying can be implemented and used. Consider the next scenario, where we filter a list of numbers and select only the numbers that are divisible by 2.

const numbers = [1, 2, 3, 4, 5, 6]; function isDivisibleBy(n, divisor){

return n % divisor === 0;

} const newNumbers = numbers.filter(n => isDivisibleBy (n, 2));

console.log(newNumbers);

//[2,4,6]

The isDivisibleBy function takes a number n and a divisor and returns true or false. When the is remainder of n divided by divisor is zero, then n is divisible by divisor .

Next, we are going to write isDivisibleBy as a manually curried function and use it.

function isDivisibleBy (divisor){

return function(n){

return n % divisor === 0;

}

} const newNumbers = numbers.filter( isDivisibleBy (2));

In this example, isDivisibleBy takes the divisor and returns a function taking the number n and returning the end result. So isDivisibleBy is a function that returns another function that returns the result.

Even if the new curried version of the function is maybe a little harder to read, it can be invoked nicely with one argument, the divisor, to create the callback for the filter method: numbers.filter(isDivisibleBy(2)) . isDivisibleBy(2) returns a function expecting a number.

Note that we need to change the order in which arguments are applied. The curried version of the isDivisibleBy first accepts the divisor and then the number n .

Let’s now analyze some other options for writing isDivisibleBy as a curried function. One other option is to use the arrow syntax.

const isDivisibleBy = divisor => n => n % divisor === 0;

In this case, we have removed some of the parentheses, curly braces, and returns but is it clearer what isDivisibleBy does? Every time we see => a new function is created.

Maybe a better option is to list all parameters on the first line using arrow functions and then used return inside the curly braces. Here is an example:

//orginal function

const isDivisibleBy = (n, divisor) => {

return n % divisor === 0;

} //curried version

const isDivisibleBy = divisor => n => {

return n % divisor === 0;

}

Again notice the reverse order of parameters in the curried version. So divisor is first, number n comes second.

Another option is to use the curry decorator from a functional library like lodash/fp. With the auto-curry decorator, we can simply write a function and the decorator will enable currying for it.

import { curry } from 'lodash/fp'; const isDivisibleBy = curry(function(divisor, n){

return n % divisor === 0;

});

Below is the same function that is rewritten with the curry decorator and the arrow syntax.

import { curry } from 'lodash/fp'; const isDivisibleBy = curry((divisor, n) => n % divisor === 0);

Here is the same arrow function rewritten with the curly braces.

import { curry } from 'lodash/fp'; const isDivisibleBy = curry((divisor, n) => {

return n % divisor === 0

});

The missing function decorator

Next, see how I think it would be nicer to enable currying on a function.

I would like to import the curry decorator from a functional library and decorate the function with it. This is not possible at the moment.

import { curry } from 'lodash/fp'; @curry

function isDivisibleBy (divisor, n){

return n % divisor === 0;

}

Again we need to write the parameters in the reverse order than the original function. This can be solved with another decorator curryRight . The curryRight decorator applies currying from the last parameter. So in order to apply parameters from right to left, we don’t need to change the original function.

import { curryRight } from 'lodash/fp'; @curryRight

function isDivisibleBy (n, divisor){

return n % divisor === 0;

}

Final Thoughts

There are different ways of making a curried function, from using functions returning functions, with the function keyword or the arrow syntax to the currying helper utilities from functional libraries.

I would prefer to enable currying with a function decorator like @curry , but since that is not available, I will stay with manually curried functions.

If you know better ways of enabling currying on an existing function I will be glad to hear your feedback. Thanks for reading and giving your feedback.