Functional programming has become very popular in recent times with one of its key concepts being Currying. In this article, we will explore what currying is, how it works in JavaScript and also its benefits to make the code look better and increase efficiency.
What is Currying in JavaScript?
Currying is a functional programming technique in JavaScript that transforms a function with multiple arguments into a series of functions, each taking a single argument.
This function does not take all the arguments together, instead it takes them one by one. Currying transforms f(a,b) into f(a)(b). It helps to create a higher-order function and also the same variable is not passed again and again.
This allows for partial application, where a function can be partially applied even if it doesn’t have all the parameters, and the result is a new function that will expect remaining arguments.
Let’s take an example and then we will break the code line by line:
//original function with multiple parameters function sum(x,y,z){ return x+y+z; } //curried version of the 'sum' function function currySum(x){ //returns a function that takes 'y' return function(y){ //returns another function that takes 'z' return function(z){ //returns the sum of x,y, and z return x+y+z; }; }; }
Now let’s break down the ‘currySum’ function step by step:
- currySum is an outer function that takes only one parameter ‘x’. It then returns another function, creating a closure over the ‘x’ parameter.
- Then there comes a middle function which takes a parameter ‘y’. It also returns another function, creating a closure over both ‘x’ and ‘y’.
- After that there is an inner function that takes a parameter ‘z’ and this function returns the result of adding ‘x’, ‘y’, and ‘z’.
Here all the functions except the outer function are anonymous functions, meaning they don’t have a name assigned to them.
Anonymous functions are often used in cases where the function is short-lived or only relevant within a specific context, such as within another function. Since these functions are not called directly by name in the code, therefore they don’t need a specific name.
Though we have an option of giving names it will only make our code lengthy and will not add much value. However, in other situations where functions are reused or more complex, giving them names can enhance code readability and maintainability.
Let’s see how we used currySum:
// using currySum function const curry = currySum(2)(3)(4) console.log(curry);
Output:
9
currySum(2) returns a new function that expects one argument(y). Similarly, currySum(2)(3) returns another function that expects one argument(z). Then finally currySum(2)(3)(4) returns the result of adding 2+3+4.
Currying can also be implemented using arrow functions. Here’s a simple code for the same:
//currying const currySum = x => y=> z => x+y+z;
Currying and Partial Application
Currying and partial application are different things, currying involves transforming a function with multiple arguments into a sequence of single-argument functions whereas in partial application it creates a new function with some arguments fixed, but it remains a regular function.
Check the code below:
//original function function sum(x,y,z){ return x+y+z; } //currying const currySum = x => y=> z => x+y+z; //partially applied function const partialApply = sum.bind(null,2,3); //usage const result = partialApply(4); console.log(result);
Output:
9
Here bind is used to create a new function called partialApply. The first argument to ‘bind’ is the context in which the function will be executed. But if ‘this’ is not relevant or does not matter for the function sum, we can set it to null.
The subsequent arguments ‘2’ and ‘3’ fix the values of the first two parameters ‘x’ and ‘y’ in the original function. partialApply is now a new function with the values of ‘x’ and ‘y’ fixed. When we invoke partialApply, we are providing the remaining value of the parameter ‘z’.
The bind method is used to create a new function from the original function with specific arguments already filled in. This makes it convenient to reuse the partially applied function with different values for the remaining parameters.
currySum invokes each curried function individually whereas partialApply directly calls the partially applied function. Therefore currying is ideal for creating a chain of functions with single parameters, while partial application is suitable for fixing specific arguments.
Benefits of Currying
Currying promotes modular code by breaking down functions into smaller, composable units. This helps in code reusability as these units can be easily combined in various ways.
It also facilitates partial application, which is valuable in scenarios where certain parameters are known first.
Other than that, it allows the creation of different versions of a function for different situations. Therefore by partially applying arguments, we can generate functions optimized for particular situations without duplicating code.
Common Mistakes
Here are some common mistakes developers make when implementing Currying in JavaScript:
- Pay attention to the order of arguments, otherwise, we may not get the desired result.
- Although currying is powerful avoid excessive nesting, known as over-currying which can make the code harder to read and understand.
- Currying may not be suitable for every situation, In some situations, it might impact performance due to multiple function closures. Therefore ensure a clear understanding of the context in which currying is applied.
But note that not all JavaScript tools or libraries support currying, you must be aware of potential compatibility issues and ensure your tools can handle curried functions appropriately.
Conclusion
Now we have covered the concept of currying thoroughly. We know what it is, its syntax, and also its benefits and mistakes. If you need more assistance, get help for your JavaScript assignment now from top experts.