Currying for JavaScript Developers with Examples

What is currying? Practical examples of currying in JavaScript. Why currying is useful in programming. How to create curried functions.

Have you noticed how from all of the classic Array methods in JavaScript to iterate and perform some transformations over that data such as map and forEach the one that never really gets understood is reduce?

Well, the same happens with Currying in Functional Programming. Everyone is all in for higher-order functions, or even pure functions with no side effects, but the minute you start talking about currying, their faces go like this:

Source: giphy

And trust me, currying is nothing that deserves such a reaction. That said, instead of just throwing the definition at your face and the classic “hello world” example, I’ll show you a few different ways where you can make use of this technique, hopefully demonstrating that this is just another tool under your JS belt and that you should use it more often.

“Hello world”

We’ve got to start somewhere, right?

The most basic example of currying is great to understand what this technique is all about.

You see, currying is nothing more than a way to transform functions that accept multiple parameters into a sequential list of functions that take only one parameter each.

https://medium.com/media/18258fabfbbae03ebb55d0817232b338/href

That’s the useless “hello world” example. The “magic” function curry is transforming our sum function into one that only takes one parameter and returns another function that again, takes one parameter and returns the sum of both numbers.

Is it difficult to implement? Heck no! In JavaScript this is relatively trivial:

https://medium.com/media/16f6ffa8c0782a7f0b926547913b384c/href

There you have 2 ways to implement it, although they’ll only work for functions with 2 arguments. We can later worry about making it more generic.

The point is that we turned a function into a list of partial functions. Take note of the term, “partial functions”, because we’ll be using it often.

Let’s take a look at a more relevant example: logging!.

Logging with a curried function

From now on, let’s assume we have a magical function curry that takes any function and properly curries it into having a list of functions, each one only accepting one parameter. I’ll show you how to implement it later, don’t worry.

Logging is something we do very often, in all of our applications we tend to have some kind of logging function that helps us debug problems. Sometimes it takes the form of console.log , others it’s Winston or a similar package. The point here is that we end up with a wrapper function that looks like this:

https://medium.com/media/d9338c4448b5341b3fbedc65c349eba3/href

Granted, you might have a variation of it or a wrapper on top of this one to simplify your logging syntax.

The aim of using currying here, is to give us some syntactic sugar when it comes to calling our logging function. And yes, syntactic sugar is actually a good thing, it can help make our code more readable and simpler to understand.

Let’s see, once we curry our log function, we get something like this:

https://medium.com/media/5a107ac61c0f684d8d44884dd6e6e6f6/href

What’s the point of doing this? The point is that we can use partial functions to give us more readable and — very important point — reusable code. Imagine you have to write 100’s debug log lines throughout your code, would you rather use that syntax or this one:

https://medium.com/media/21fa651d810a8005dfdc7be37d358800/href

By using currying I pre-filled 2 of the 4 parameters that log receives. I’m not using the cLog function anywhere, but I can use logDebug everywhere and I can create similar versions of it with different pre-fills:

https://medium.com/media/9b54ff4819f207c34407695cef7fcc41/href

You see how we turned our original log function that could do everything but required 4 parameters, into multiple individual functions that do one thing but require fewer parameters. The point here is that it’s going to be a lot easier to write and much cleaner to read something like errorMsg(errorObj) than log(“ERROR”, Date(), “There is an error here”, errorObj) , don’t you think?

Currying in this case provides several benefits:

  1. It helps us make our code more readable.
  2. It cleans up the code by abstracting some of the less important and repeatable values.
  3. It helps us re-use our code in multiple ways.

Filtering

Coming up with a generic filtering function for our data can be a great achievement. Finding a way to give yourself the power to enter a few parameters and then get the exact data you need is great. The problem is that filtering parameters can start to stack up, and then your filtering calls end up looking like this:

filter(data, 'first_name', 'John', 'eq')

And yes, if you’re the one who implemented the function, you know what it means. If on the other hand, you’re just seeing it written there with no further context, you’ll have to guess what each attribute means, especially for that last one.

Look at the following example:

https://medium.com/media/ce107dc368cd9af1e211f254507b5a60/href

The filter function is a crude wrapper around the filter method so that we don’t have to worry about creating that lambda function every time. Instead this abstracts us from it and we can just worry about our filtering parameters. Yes, there are better ways to do this, but this is not the point, the point is about to come.

Through currying, we can create partial versions of filter to capture common filtering options we might want to have. Things like filtering by age, or by name, so that we can simplify our syntax, as we did before with the logging example.

https://medium.com/media/b24b02760d2722067a22d407e9fb3d0b/href

At the start of the snippet above, we defined a set of pre-set filters. We can then see the results at the end: a much more readable scenario and a lot more flexible too.

The output from that example, just so we’re clear, is:

//olderThan30
[
{
first_name: 'Fernando',
last_name: 'Doglio',
age: 38,
city: 'Madrid'
},
{ first_name: 'John', last_name: 'Doe', age: 40, city: 'NY' },
{
first_name: 'Optimus',
last_name: 'Prime',
age: 100000,
city: 'Cybertron'
}
]
----
//olderThanTime
[
{
first_name: 'Optimus',
last_name: 'Prime',
age: 100000,
city: 'Cybertron'
}
]
----
//me
[
{
first_name: 'Fernando',
last_name: 'Doglio',
age: 38,
city: 'Madrid'
}
]

As you can see, this is another example where currying helps to simplify the syntax of your logic, make it more readable, and provide you with the flexibility to re-use your code in many ways everywhere you need to.

Let’s now look at the best part: implementing the curry function.

The Implementation

Let’s take a look at 2 versions of the curry function. The first one is going to be the one I’ve been using throughout the entire article, and then I’ll throw a curveball your way.

Like I’ve shown you, the curry function needs to return a sequence of callable functions that take one parameter each, based on the number of parameters for the original function. We can do this with a little recursion magic:

https://medium.com/media/d6d30865e68721f1b3502bb0b4e7590e/href

What the above code does is:

  1. It returns a new function called curried which is going to start capturing parameters inside the params array.
  2. If not called with the exact number of attributes the original function receives, it’ll assume it’s a partial call, thus it’ll return a new function.
  3. The new function receives another parameter, calls the original, and concatenates both lists of parameters together. Thus collecting all individual parameters.
  4. Now we go back to point 2, until of course, we’ve collected all required parameters, and then we call the original function using the apply method (which lets us pass all attributes as an array).

This works, you can test it with the examples given so far. But if we go back to the examples, especially the filtering ones, it feels like we’re not pushing our curry logic to the max.

It would be really cool if we could do something like this:

https://medium.com/media/9b02a92532ae30770f9f29ea52b8bef2/href

Essentially, it would be great to have some kind of wildcard value we could provide, so that it gets resolved during the execution of the filter. But our curry function doesn’t allow for it, not right now though.

We can allow for 1 wildcard to be used with the following logic:

https://medium.com/media/385dfc236b77df761b03312210ca4413/href

Now if a wildcard is used, when it’s time to call the original function, we return yet another function wrapping it. This new function will ask for the actual value of the wildcard before performing the final call.

That way, we gain even extra flexibility, and if you have the time and energy, you could also add support for a variable number of wildcards to be used across the currying chain. I’ll leave that to you!

Is currying a bit more understandable now? Does it make more sense?

Build applications differently

OSS Tools like Bit offer a new paradigm for building modern apps.

Instead of developing monolithic projects, you first build independent components. Then, you compose your components together to build as many applications as you like. This isn’t just a faster way to build, it’s also much more scalable and helps to standardize development.

It’s fun, give it a try →

An independent product component: watch the auto-generated dependency graph

Conclusion

Currying is definitely a powerful tool, one that can potentially take your code to the next level, but to do so, you have to fully understand how it works. Now that you do, you can probably use the currying methods from libraries such as lodash instead of building your own every time.

Do you still have questions? Leave them in the comments and I’ll do my best to help out!


Currying for JavaScript Developers with Examples was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Fernando Doglio

What is currying? Practical examples of currying in JavaScript. Why currying is useful in programming. How to create curried functions.

Have you noticed how from all of the classic Array methods in JavaScript to iterate and perform some transformations over that data such as map and forEach the one that never really gets understood is reduce?

Well, the same happens with Currying in Functional Programming. Everyone is all in for higher-order functions, or even pure functions with no side effects, but the minute you start talking about currying, their faces go like this:

Source: giphy

And trust me, currying is nothing that deserves such a reaction. That said, instead of just throwing the definition at your face and the classic “hello world” example, I’ll show you a few different ways where you can make use of this technique, hopefully demonstrating that this is just another tool under your JS belt and that you should use it more often.

“Hello world”

We’ve got to start somewhere, right?

The most basic example of currying is great to understand what this technique is all about.

You see, currying is nothing more than a way to transform functions that accept multiple parameters into a sequential list of functions that take only one parameter each.

That’s the useless “hello world” example. The “magic” function curry is transforming our sum function into one that only takes one parameter and returns another function that again, takes one parameter and returns the sum of both numbers.

Is it difficult to implement? Heck no! In JavaScript this is relatively trivial:

There you have 2 ways to implement it, although they’ll only work for functions with 2 arguments. We can later worry about making it more generic.

The point is that we turned a function into a list of partial functions. Take note of the term, “partial functions”, because we’ll be using it often.

Let’s take a look at a more relevant example: logging!.

Logging with a curried function

From now on, let’s assume we have a magical function curry that takes any function and properly curries it into having a list of functions, each one only accepting one parameter. I’ll show you how to implement it later, don’t worry.

Logging is something we do very often, in all of our applications we tend to have some kind of logging function that helps us debug problems. Sometimes it takes the form of console.log , others it’s Winston or a similar package. The point here is that we end up with a wrapper function that looks like this:

Granted, you might have a variation of it or a wrapper on top of this one to simplify your logging syntax.

The aim of using currying here, is to give us some syntactic sugar when it comes to calling our logging function. And yes, syntactic sugar is actually a good thing, it can help make our code more readable and simpler to understand.

Let’s see, once we curry our log function, we get something like this:

What’s the point of doing this? The point is that we can use partial functions to give us more readable and — very important point — reusable code. Imagine you have to write 100’s debug log lines throughout your code, would you rather use that syntax or this one:

By using currying I pre-filled 2 of the 4 parameters that log receives. I’m not using the cLog function anywhere, but I can use logDebug everywhere and I can create similar versions of it with different pre-fills:

You see how we turned our original log function that could do everything but required 4 parameters, into multiple individual functions that do one thing but require fewer parameters. The point here is that it’s going to be a lot easier to write and much cleaner to read something like errorMsg(errorObj) than log("ERROR", Date(), "There is an error here", errorObj) , don’t you think?

Currying in this case provides several benefits:

  1. It helps us make our code more readable.
  2. It cleans up the code by abstracting some of the less important and repeatable values.
  3. It helps us re-use our code in multiple ways.

Filtering

Coming up with a generic filtering function for our data can be a great achievement. Finding a way to give yourself the power to enter a few parameters and then get the exact data you need is great. The problem is that filtering parameters can start to stack up, and then your filtering calls end up looking like this:

filter(data, 'first_name', 'John', 'eq')

And yes, if you’re the one who implemented the function, you know what it means. If on the other hand, you’re just seeing it written there with no further context, you’ll have to guess what each attribute means, especially for that last one.

Look at the following example:

The filter function is a crude wrapper around the filter method so that we don’t have to worry about creating that lambda function every time. Instead this abstracts us from it and we can just worry about our filtering parameters. Yes, there are better ways to do this, but this is not the point, the point is about to come.

Through currying, we can create partial versions of filter to capture common filtering options we might want to have. Things like filtering by age, or by name, so that we can simplify our syntax, as we did before with the logging example.

At the start of the snippet above, we defined a set of pre-set filters. We can then see the results at the end: a much more readable scenario and a lot more flexible too.

The output from that example, just so we’re clear, is:

//olderThan30
[
{
first_name: 'Fernando',
last_name: 'Doglio',
age: 38,
city: 'Madrid'
},
{ first_name: 'John', last_name: 'Doe', age: 40, city: 'NY' },
{
first_name: 'Optimus',
last_name: 'Prime',
age: 100000,
city: 'Cybertron'
}
]
----
//olderThanTime
[
{
first_name: 'Optimus',
last_name: 'Prime',
age: 100000,
city: 'Cybertron'
}
]
----
//me
[
{
first_name: 'Fernando',
last_name: 'Doglio',
age: 38,
city: 'Madrid'
}
]

As you can see, this is another example where currying helps to simplify the syntax of your logic, make it more readable, and provide you with the flexibility to re-use your code in many ways everywhere you need to.

Let’s now look at the best part: implementing the curry function.

The Implementation

Let’s take a look at 2 versions of the curry function. The first one is going to be the one I’ve been using throughout the entire article, and then I’ll throw a curveball your way.

Like I’ve shown you, the curry function needs to return a sequence of callable functions that take one parameter each, based on the number of parameters for the original function. We can do this with a little recursion magic:

What the above code does is:

  1. It returns a new function called curried which is going to start capturing parameters inside the params array.
  2. If not called with the exact number of attributes the original function receives, it’ll assume it’s a partial call, thus it’ll return a new function.
  3. The new function receives another parameter, calls the original, and concatenates both lists of parameters together. Thus collecting all individual parameters.
  4. Now we go back to point 2, until of course, we’ve collected all required parameters, and then we call the original function using the apply method (which lets us pass all attributes as an array).

This works, you can test it with the examples given so far. But if we go back to the examples, especially the filtering ones, it feels like we’re not pushing our curry logic to the max.

It would be really cool if we could do something like this:

Essentially, it would be great to have some kind of wildcard value we could provide, so that it gets resolved during the execution of the filter. But our curry function doesn’t allow for it, not right now though.

We can allow for 1 wildcard to be used with the following logic:

Now if a wildcard is used, when it’s time to call the original function, we return yet another function wrapping it. This new function will ask for the actual value of the wildcard before performing the final call.

That way, we gain even extra flexibility, and if you have the time and energy, you could also add support for a variable number of wildcards to be used across the currying chain. I’ll leave that to you!

Is currying a bit more understandable now? Does it make more sense?

Build applications differently

OSS Tools like Bit offer a new paradigm for building modern apps.

Instead of developing monolithic projects, you first build independent components. Then, you compose your components together to build as many applications as you like. This isn’t just a faster way to build, it’s also much more scalable and helps to standardize development.

It’s fun, give it a try →

An independent product component: watch the auto-generated dependency graph

Conclusion

Currying is definitely a powerful tool, one that can potentially take your code to the next level, but to do so, you have to fully understand how it works. Now that you do, you can probably use the currying methods from libraries such as lodash instead of building your own every time.

Do you still have questions? Leave them in the comments and I’ll do my best to help out!


Currying for JavaScript Developers with Examples was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Fernando Doglio


Print Share Comment Cite Upload Translate Updates
APA

Fernando Doglio | Sciencx (2022-02-09T07:16:11+00:00) Currying for JavaScript Developers with Examples. Retrieved from https://www.scien.cx/2022/02/09/currying-for-javascript-developers-with-examples/

MLA
" » Currying for JavaScript Developers with Examples." Fernando Doglio | Sciencx - Wednesday February 9, 2022, https://www.scien.cx/2022/02/09/currying-for-javascript-developers-with-examples/
HARVARD
Fernando Doglio | Sciencx Wednesday February 9, 2022 » Currying for JavaScript Developers with Examples., viewed ,<https://www.scien.cx/2022/02/09/currying-for-javascript-developers-with-examples/>
VANCOUVER
Fernando Doglio | Sciencx - » Currying for JavaScript Developers with Examples. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/02/09/currying-for-javascript-developers-with-examples/
CHICAGO
" » Currying for JavaScript Developers with Examples." Fernando Doglio | Sciencx - Accessed . https://www.scien.cx/2022/02/09/currying-for-javascript-developers-with-examples/
IEEE
" » Currying for JavaScript Developers with Examples." Fernando Doglio | Sciencx [Online]. Available: https://www.scien.cx/2022/02/09/currying-for-javascript-developers-with-examples/. [Accessed: ]
rf:citation
» Currying for JavaScript Developers with Examples | Fernando Doglio | Sciencx | https://www.scien.cx/2022/02/09/currying-for-javascript-developers-with-examples/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.