menu sluiten
Contact

Amsterdam
Pedro de Medinalaan 87a/b, 1086 XP Amsterdam
Nederland +31 (0)85-888 33 31

Breda
Neerloopweg 36, 4814 RS Breda
Nederland +31 (0)85-888 33 31

Antwerpen
Veldkant 33B, 2550 Kontich
België +32 (0)3 444 11 08

info@jstack.eu

16 maart 2016

How to get started with currying in functional programming

If you are getting into functional programming lately, you might be looking into some of the techniques that are used in this way of thinking. One of those techniques is currying. When I first started out, I understood what it was… but not how to use it in day to day programming.

Today I’ll try to illustrate currying through JavaScript code. I’ll also demonstrate the curry function in the Ramda library. This is what currying is in its simplest form.

1
2
const add = (a) => (b) => a + b;
console.log( add(1)(2) );         // prints 3

The function add is “curried”, that means you can partially apply some of the parameter it needs. You could define functions where you already apply some of these parameters:

1
2
3
4
const add = (a) => (b) => a + b;
const add10 = add(10);

console.log( add10(2) );        // prints 12

Okay, that’s not that bad, but this is also completely useless… why would I curry an add function? I will never define a function called add10? You’d be surprised on how many function you define when you are writing functional code (more about this topic later). But I agree that this isn’t really a real life example!

So where’s that realistic example?

1
2
const people = [{ name: ‘john’ }, { name: ‘jack’ } /*, …*/ ];
const getPersonThatStartsWith = (partial) => people.filter((person) => person.name.startsWith(partial));

Here we have just your average filter on some input the user gives us (a partial name for example “joh”).

When we are thinking functionally we notice that we have the opportunity to abstract the filter function so we can reuse it later.

1
2
3
const people = [{ name: ‘john’ }, { name: ‘jack’ } /*, …*/ ];
const partialNameFilter = (partial, person) => person.name.startsWith(partial);
const getPersonThatStartsWith = (partial) => people.filter(partialNameFilter)

There is a problem here… we need to pass partial to the partialNameFilter, but we are unable to do this because we want to call the filter multiple times (once for every person in the people array). We will need to partially apply the partial to the filter (up front). This is an indication that you need to curry your function.

1
2
3
const people = [{ name: ‘john’ }, { name: ‘jack’ } /*, …*/ ];
const partialNameFilter = R.curry((partial, person) => person.name.startsWith(partial));
const getPersonThatStartsWith = (partial) => people.filter(partialNameFilter(partial))

By using the Ramda function R.curry, we are able to partially apply parameters to the function. The powerful part is that we are still able to call the function with multiple parameters at the same time. It allows us to partially apply, but does not require it!

I could therefore call the filter function like this

1
2
partialNameFilter(‘joh’, { name: ‘john’ });
partialNameFilter(‘joh’)({ name: ‘john’ });

Now this function is curried and can be used in multiple functional environments like the example above with the filter function.

 

Currying in functional programming

Starting out with functional programming might seem daunting at first, but if you are able to shift your mindset towards functions and passing them along as values, you will have an exciting time ahead of you!

Meer weten?

Neem contact op met Danny. Hij denkt graag met u mee in een persoonlijk gesprek.

info@jstack.eu +31 (0)85-888 33 31

Interessant? Deel dit artikel met een vriend(in) of collega!

Vragen over dit onderwerp?

Onze experts denken graag met u mee


Gerelateerde berichten