Ezekiel Lawson I'm a software developer with experience in web technologies like Javascript, Vue.js, HTML, and CSS. I love teaching and sharing my technical ideas through articles.

Understanding JavaScript currying

5 min read 1440

Understanding JavaScript currying

Currying is a concept from lambda calculus, but don’t let that freak you out — it’s quite simple to implement.

Currying is a function that takes one argument at a time and returns a new function expecting the next argument. It is a transformation of functions that translates a function from callable as f(a, b, c) into callable as f(a)(b)(c).

In this article, we’re going to explore what currying is in Javascript, why and where you should use currying, and how to implement it with code examples.

What is currying in JavaScript?

Currying simply means evaluating functions with multiple arguments and decomposing them into a sequence of functions with a single argument.

In other terms, currying is when a function — instead of taking all arguments at one time — takes the first one and returns a new function, which takes the second one and returns a new function, which takes the third one, etc. until all arguments are completed.

Why should I use currying?

There are several reasons why currying is ideal:

  • Currying is a checking method to make sure that you get everything you need before you proceed
  • It helps you to avoid passing the same variable again and again
  • It divides your function into multiple smaller functions that can handle one responsibility. This makes your function pure and less prone to errors and side effects
  • It is used in functional programming to create a higher-order function
  • This could be personal preference, but I love that it makes my code readable

How does currying work?

Currying is a function that accepts multiple arguments. It will transform this function into a series of functions, where every little function will accept one argument:

Noncurried version//
const add = (a, b, c)=>{
return a+ b + c
}
console.log(add(2, 3, 5)) // 10

Curried version//
const addCurry =(a) => {
return (b)=>{
return (c)=>{
return a+b+c
}
}
}
console.log(addCurry(2)(3)(5)) // 10

Currying in Javascript may be a little bit tricky to understand in terms of its definition, but it will become clear as we implement it.

So, let’s dive into more code examples.

Example one: A simple, three-parameter function

First, I’m going to create a simple function that accepts three parameters:

We made a custom demo for .
No really. Click here to check it out.

const add =(a, b, c)=>{
return a+b+c
}
console.log(add(2, 3, 5)) // 10

After outputting this function, the result is 10.

What happened here is that this function is adding all the parameters of the numbers which we have passed.

Now, this first example is just a simple function that accepts multiple parameters.

How do I convert an existing function to a curried version?

Example two: Converting an existing function into a curried function

Let’s try this second example and see how we can implement the curry function.

In this example, this function is going to accept one argument and return a series of functions:

const addCurry =(a) => {
return (b)=>{
return (c)=>{
return a+b+c
}
}
}

This is the curry implementation of the function. If we output this, the result will be 10:

console.log(addCurry(2)(3)(5)) // 10

In the first example, we created a function addCurry that accepted three arguments a, b, and c, added their sum a+b+c, (2)+(3)+(5), and returned the output as 10.

This second example showed how we implemented the same function but with a curried version that takes one argument a and returns a function that takes another argument b, which returns a function that takes another argument c, and that function returns their sum, which gave us the same output as example one: 10.

What we have done here is a nested function, so each of these functions takes one argument that returns another argument and the function doesn’t complete until it receives all parameters.

Example three: Creating a friend request curry function

In this example, we are going to create a simple curry function where a user sends a friend request to his friend John:

const sendRequest(greet){
return function(name){
return function(message){
return `${greet} ${name}, ${message}`
}
}
}
sendRequest('Hello')('John')('Please can you add me to your Linkedin network?')

Output:

"Hello John, Please can you add me to your Linkedin network?"

We created a function sendRequest that requires only one argument, greet, and it returns the name of the person and the message we want to send to the user. Then, when we invoked the function, it outputted the message.

Basic vs. advanced currying techniques

Basic currying

const getPanCakeIngredients = (ingredient1) =>{
return (ingredient2) => {
return (ingredient3) => {
return ${ingredient1}, ${ingredient2}, ${ingredient3}; } } } getPanCakeIngredients('Egg')('flour')('milk');

This code example is a basic way of implementing currying.

In the above example, we created a function getPanCakeIngredients that takes ingredient 1 as a single argument and returns a series of functions that contain the other ingredients we need to make the pancake.

The function isn’t complete until it receives all parameters, which means if the ingredients for the pancake are not complete, the function won’t return any good result.

Advanced currying

Here is a code example of advanced currying:

const curry =(fn) =>{
 return curried = (...args) => {
if (fn.length !== args.length){
return curried.bind(null, ...args)
}
return fn(...args);
};
}
const totalNum=(x,y,z) => {
return x+y+z 
} 
const curriedTotal = curry(totalNum);
console.log(curriedTotal(10) (20) (30));

In the example above, we created a function that requires a fixed number of parameters.

It receives a function curry as the outer function. This function is a wrapper function. It returns another function named curried, which receives an argument with the spread operator ( ...args), and it compares the function length fn length.

The function length means that whatever the number of parameters we pass here, it will reflect in the length property of the function.

But the argument will increase every time. If the number of the parameters we need is not equal, it is going to return curried. If we call bind, this creates a new function and we pass the ( ...args).

N.B., bind creates a new function.

Modern currying with ES6

As my bonus tip, here is a modern way of implementing currying using the ES6 arrow function. It helps you write less code:

const sendRequest = greet => name => message =>
`${greet} ${name}, ${message}`
sendRequest('Hello')('John')('Please can you add me to your Linkedin network?')

Output:

"Hello John, Please can you add me to your Linkedin network?"

Currying can be used to manipulate the DOM in Javascript

Ready to put currying into action? Here is a simple CodePen example of how to manipulate the DOM using currying:

Curry Dom example

Add External Stylesheets/Pens Any URL’s added here will be added as s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing. JavaScript Preprocessor Babel includes JSX processing.

Currying vs. partial application

Now that you know how currying works, what is the difference between currying and a partial application? This is one question programmers keep asking.

I finally have the answer to this question. But before I dive deeper into this explanation with some code examples, it would be best if we familiarize ourselves with their definitions.

  • Currying: a function that accepts multiple arguments. It will transform this function into a series of functions, where every little function will accept a single argument until all arguments are completed
  • Partial application: a function is partially applied when it is given fewer arguments than it expects and returns a new function expecting the remaining arguments

Knowing the definitions aren’t enough for us to understand their differences. You’ve seen currying in action, but this is an example of partial application:

const addPartial=(x,y,z) => {
return x+y+z 
}
var partialFunc= addPartial.bind(this,2,3);
partialFunc(5); //returns 10

What we did here isn’t a curried version, but we did a partial application of the addPartial function. We created a simple function that adds a list of numbers and returns their output.

N.B., a function is called a partial application when some of the argument it passes is incomplete.

Currying and partial application are not really different; they are related, but they have different theories and applications.

The partial application converts a function to another function, but with smaller arity.

Conclusion

For developers, currying can feel complicated. While it is tricky to understand, you will learn it better when you implement it in your JavaScript projects.

I have implemented currying in some of my projects and learned by practice. These are some things I have used currying for:

  • Currying can be used to manipulate the DOM in Javascript
  • It can be used to trigger event listeners
  • Currying can be used when you want to create a function that will receive only single arguments

Thanks for reading this article, and please feel free to leave any comments you have. I’m open to learning from you. Cheers!

: Debug JavaScript errors easier by understanding the context

Debugging code is always a tedious task. But the more you understand your errors the easier it is to fix them.

LogRocket allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to find out exactly what the user did that led to an error.

LogRocket records console logs, page load times, stacktraces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!

.
Ezekiel Lawson I'm a software developer with experience in web technologies like Javascript, Vue.js, HTML, and CSS. I love teaching and sharing my technical ideas through articles.

Testing accessibility with Storybook

One big challenge when building a component library is prioritizing accessibility. Accessibility is usually seen as one of those “nice-to-have” features, and unfortunately, we’re...
Laura Carballo
4 min read

Leave a Reply