What is currying in JavaScript? Complete Guide
Functional programming has been around for a long time and is a popular programming paradigm. In contrast to Object Oriented Programming, Functional Programming adopts a different approach in which we only utilize functions to construct reliable software. Functional programming has many applications, one of which is function currying.
We will learn about function currying in JavaScript in this post. We will also look at its implementation and use in real-world scenarios. In addition, we will go through an advanced currying implementation so that we may learn the true potential of currying.
What is function currying in JavaScript?
Function currying is not a JavaScript-specific thing. It is a programming pattern where we give only a few instead of passing all the arguments to the function at once. The function returns another function to which we can pass on a few more arguments. This loop may go on forever, which is one of the significant advantages of function currying. It is impossible to create a function taking an infinite number of arguments at once, but we can achieve it using function currying.
For example, instead of calling an add()
method like add(num1, num2, num3)
, we may call it as add(num1)(num2)(num3)
. In this manner, we may use the add()
function with any arbitrary number of arguments, which we cannot accomplish with the non-curried add function.
Advantages of function currying in JavaScript
Function currying is an important programming paradigm in JavaScript. It has several advantages, some of which are as follows:
- The currying function in JavaScript is a higher-order function. Higher-order functions are those that either take another function as an argument or return a function. These are the heart of functional programming and make complex things feel incredibly simple.
- In function currying, we break the actual function into several pieces, each of which takes a separate argument. Each of these functions can perform its assigned job. It makes the code more secure and maintainable.
Simple function currying implementation in JavaScript
As we already discussed, in a curried function, instead of accepting all the arguments at once, it takes only a few arguments at a time and returns another function to which we provide a different set of arguments.
To understand it better, let’s implement a simple curried function:
function add(num1) {
return function (num2) {
return function (num3) {
return num1 + num2 + num3;
}
}
}
const sum = add(1)(2)(3);
console.log(sum);
Code language: JavaScript (javascript)
Let us now break down the code part by part. First, we create an add()
function, which takes only one argument. It then returns another anonymous function, which also takes only one argument. The anonymous function returns another anonymous function that takes only one argument. It then adds all three arguments of the parent functions and returns the result. Since the last anonymous function forms a closure with its parent functions, it has access to their arguments.
At first, the code may seem tricky to understand, but once you are comfortable with function currying, it’s just a cakewalk.
Currying using ES6 syntax in JavaScript
Once comfortable with function currying in JavaScript, we may utilize the modern ES6 syntax for writing curried functions. ES6 comes with arrow functions, a shorthand for creating functions in JavaScript. We may use arrow functions to modify our add()
function implementation that we discussed earlier.
const add = num1 => num2 => num3 => num1 + num2 + num3;
Code language: JavaScript (javascript)
The shorthand notation has simplified the implementation to a great extent. It looks more straightforward and cleaner now.
Implementing an advanced currying function
Implementing a curried version for every function is not a good idea. A better way to do so is to implement a currying function that transforms any function into its curried version. This way, we can save a lot of time implementing curried versions of functions from scratch by just transforming them using our currying function.
Below is the code for our advanced currying function:
function curryFunction(func) {
return function curriedFunction(...args) {
if (args.length >= func.length) {
return func.call(this, ...args);
}
return function (..._args) {
return curriedFunction.call(this, ...args, ..._args);
}
}
}
Code language: JavaScript (javascript)
Let us now break down the code part by part. Firstly, we declare a function curry()
that accepts another function as an argument. The function curry()
will return the curried version of the supplied function. The function curriedFunction()
returned from the function curry()
will check if the number of arguments received is greater than or equal to the arguments required by the function func
, and If it is true, we will call the function func
with those arguments. We do this because there is no point in currying if we have passed all the required arguments to the function at once. But, if the arguments supplied are less than what was expected by the function func
, we will return another function. It will call the function curriedFunction()
with the remaining set of arguments. This process continues till the number of arguments expected by the function func
is less than or equal to the arguments supplied.
The process may seem complicated if you are not comfortable with concepts like recursion. Otherwise, it’s quite simple if we have understood the process well enough.
Let us now use our implementation to convert the function add()
to its curried version:
function add(num1, num2, num3) {
return num1 + num2 + num3;
}
const curriedAdd = curryFunction(add);
const sum = curriedAdd(1)(2)(3);
console.log(sum);
Code language: JavaScript (javascript)
Partial functions
Partial functions are kind of similar to curried functions. The main distinction between the two is that a partial function already has some of its arguments set. To put it simply, we utilize the function provided by a curried function as a base function to accomplish a certain task with a few defined sets of arguments.
Let us take an example:
Partial multiplication function
Consider the following function multiply()
:
function multiply(num1, num2) {
return num1 * num2;
}
Code language: JavaScript (javascript)
It takes two arguments: num1
and num2
. The result returned from this function is the multiplication of the numbers num1
and num2
. Imagine a scenario where we want to get the result of the multiplication of any number by 3. In that case, we will be using the multiply()
function with the following arguments: 3
and num2
. The problem here is that if there are multiple occurrences where we need to get the result of multiplication of 3 and a number num2
, we will be providing the argument 3
again and again. To solve this issue, we will curry the function multiply()
and get a new function from it with the first argument fixed as 3
. Therefore, whatever we pass to the function returned from the function multiply()
will be multiplied by 3 and return the result.
const curriedMultiply = curryFunction(multiply);
const multiplyBy3 = curriedMultiply(3);
const result = multiplyBy3(5);
console.log(result);
Code language: JavaScript (javascript)
Conclusion
Function currying is a programming pattern in which we pass only a few arguments to the function rather than all of them at once. The function returns another function to that we may provide additional parameters. Implementing a curried version of every function is a tedious task, therefore, a currying function is a better option. A currying function takes a function as an argument and returns the curried version of that function. Partial functions are similar to curried functions having a few of their arguments fixed.
This article hopefully provided you with some new information. Share it with your friends if you enjoyed it. Also, please provide your feedback in the comments section.
Thank you so much for reading 😄
Sharing is caring
Did you like what Varun Tiwari wrote? Thank them for their work by sharing it on social media.
No comments so far
Curious about this topic? Continue your journey with these coding courses: