TIL A practical Curry Example
POSTED ON:
TAGS: curry advanced javascript
via A practical example of how to use Currying in Javascript
Currying... is a programming technique where you take a function with multiple arguments, and you turn it into smaller sequential functions where you pass one argument at a time.
Example of Currying #
// A curried function to add two numbers
function add(x) {
return function(y) {
return x + y;
}
}
// Using the curried function
const add5 = add(5); // returns a function that adds 5 to a given number
console.log(add5(3)); // Output: 8
console.log(add5(7)); // Output: 12
This example is always dumb to me.
Why would you hide that data? I know many reasons why you should, but that edge-case is only important if you have others extending your locked-down code. Which is rare unless I'm building a library.
But not because currying is pointless, is just because that example is rather unpractical in my opinion.
Okay like a real use-case #
You have a list like this:
const list = [
{
id: 1,
name: 'Steve',
email: 'steve@example.com',
},
{
id: 2,
name: 'John',
email: 'john@example.com',
},
{
id: 3,
name: 'Pamela',
email: 'pam@example.com',
},
{
id: 4,
name: 'Liz',
email: 'liz@example.com',
},
];
To filter, you do something like this:
// Step 1 - Filtering only John
const noJohn = list.filter(item => item.name !== 'John');
// Step 2 - Making it generic
const filterByName = (list, name) => {
return list.filter(item => item.name !== name);
}
// Step 3 - Maybe abstract it a bit
// NOTE: this will error since it doesn't know what "name" is
const filtering = item => item.name !== name;
const filterByName = (list, name) => {
return list.filter(filtering);
}
// Step 4 - Well what if you can curry?
// we add another function on top of the previous
const filtering = (name) => (item) => item.name !== name;
const filterByName = (list, name) => {
return list.filter(filtering(name));
}
// Step 4 - but without arrow functions
function filterByName(list, name) {
return list.filter(function(nameToFilter) {
// nameToFilter is declared at this point
return function(item) {
// item is declared here
return item.name !== nameToFilter;
}
}(name)); // name is being passed to the return statement!
}
Related TILs
Tagged: curry