DEV Community

Cover image for Beginners Guide To Higher Order Functions, Partial Functions and Currying
Kingsley Ubah
Kingsley Ubah

Posted on • Originally published at ubahthebuilder.tech

Beginners Guide To Higher Order Functions, Partial Functions and Currying

Before we begin with Higher Order Functions and Currying, we need to first establish what a normal function looks like:

function  returnEven () {
    return 2; // returns a single value
}

function  addEven () {
    return 2+2; // returns an expression
}
Enter fullscreen mode Exit fullscreen mode

A Higher Order function is simply a function which returns another function just as a normal function would return a straight value. Since the function has another function in it, it would require at least two rounds of parameters for a higher order function to be fully resolved.

You can use higher order functions to create partially applied functions. A partially applied function is a function which is partially applied and not fully resolved i.e hasn’t received the complete number of arguments it requires (arity) to fully resolve.

With a partially applied function, you pass some parameters and you get back a function that locks those parameters in place while taking more parameters.

Analogy: Let’s assume you find a starving dog with pale skin and thin body amongst other typical gaunt features. For every kind of food you give to it (parameter), a new dog (new function) is formed. A new dog means that the dog becomes less pale, or maybe gains more weight etc. However, the dog is not fully healthy just as a partially applied function is not fully resolved yet. However at some point after supplying the right number of nutrients (and parameters), the dog becomes fully healthy.

As you can see, the biggest use of partial functions is to create ** parameters of single responsibility**. For every parameter you supply to that function, a new function with new functionality is formed. That function thereby formed will take another set of parameter to make a new function and so on, until the function is fully resolved.

Let’s take a look at some use case. Consider a scenario. We have two teams, a match venue and an official. The venue and official are fixed. Regardless of the game played, they both do not change. The teams however change. One team will make use of both the venue and official today, and another team will the next time.

const venue = {
capacity: 65,000,
address: Wembley
}

const official = {
name: Carl Mason,
age: 47
}

const teamA = {
name: Man Utd,
position: 2nd,
time: 11pm - 1pm
}

const teamB = {
name: Liverpool,
position: 4th",
time: “2pm – 4pm”
}

function mergeBasicInfos(venue, official) {
const { capacity , address } = venue;
const { name } = official;
const basicInfo = {
capacity,
address,
referee: name,
};
return team => {
return { ...basicInfo, ...team };
};
}

const GameWithVenueAndOfficial = mergeBasicInfos(venue, official);
Enter fullscreen mode Exit fullscreen mode

The objective is very simple. Using the concepts of Higher Order Functions and Partial Applications, we want to create a partially applied function which already has one round of parameter (the base info - Venue and official) locked in and now has to take either of the two variable parameters (either of the teams) as the next round of argument. So when it’s time for teamA, we do this:

const TeamAGame = GameWithVenueAndOfficial(teamA); //This is currying

// {
// name: 'Man Utd',
// position: '2nd'
// time: '12pm - 2pm',
// capacity: 65,000
// address: 'Wembley',
// referee: 'Carl Mason'
// }
Enter fullscreen mode Exit fullscreen mode

When it’s time for teamB, we do this:

const TeamBGame = GameWithVenueAndOfficial(teamB); //Also currying

// {
// name: 'Liverpool',
// position: '4th'
// time: '2pm - 4pm',
// capacity: 65,000
// address: 'Wembley',
// referee: 'Carl Mason'
// }
Enter fullscreen mode Exit fullscreen mode

The base information never changes. It remains locked thanks to the first action we called: mergeBasicInfos().

And with that, we have multiple rounds of parameters which have a single responsibility:

  • First parameter is to establish the venue and match official,
  • Second set of parameter is to supply the particular team to play the match

As you can see, Higher Order Functions are quite apt when it comes to abstracting functionality and locking up parameters.

CURRYING

Currying is the process of taking a function which requires multiple rounds of parameters and returning a series of functions which takes exactly one argument each.

Analogy: If I were to reuse the previous analogy of a dog, I could say that currying happens exactly at the time you feed the dog once and move it from one state to another state.

Currying has to do with the time a function takes in one round of argument to either fully resolve or to create another partially applied function.

With Currying, you can pass in a round of argument into a higher order function, pass that function to a variable and pass in a new round of argument into that function before passing it to another variable and so on:
Now, let’s illustrate currying in terms of code. To this so, I’ll refer to this simple code from medium :

function multiply(a) {
return (b) => {
return (c) => {
return a * b * c
}
}
}

const mul1 = multiply(1); //A curry action
const mul2 = mul1(2); // Another curry
const result = mul2(3); // Another curry, finally resolves
log(result); // 6
Enter fullscreen mode Exit fullscreen mode

Every time you curry a function, you create a new function that has the previous parameter locked in and now takes in just one argument to either create another partially applied function or completely resolve. It’s really that simple.

The ability to create single responsibility parameters is a very useful feature of HOC’s and currying, as we saw in my .Thanks to it, we created a form of abstract function which was now used in two different scenarios (two different teams playing). We can also replicate this with many other ideas and functionalities. The possibilities are limitless.

CONCLUSION

I am now going to conclude this article with the following points:

  • A higher order function is a function which returns another function instead of a straight value or expression
  • Partial application of a function occurs when a function receives a fresh round of argument and thus has a new form
  • You can use currying to pass around partially applied functions until it is fully resolved.

NOTE: If you are looking for a good beginner friendly book for learning web development, I’ll highly recommend HTML To React (aff)

To support my work, you can buy me my favourite fruit:

Thanks for reading and see you soon.

Top comments (7)

Collapse
 
pengeszikra profile image
Peter Vivo

maybe arrow functions is cleaner represent the currying ( common way in my use case )

const multiply = a => b => c => a * b * c;
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ubahthebuilder profile image
Kingsley Ubah

Yes. Just wanted to keep things as simple as possible.

Collapse
 
shareef profile image
Mohammed Nadeem Shareef

I would love to see more code examples and this is an awesome 😎 article

Collapse
 
eljayadobe profile image
Eljay-Adobe

The curried notation can be made a bit more succinct.

const cf = (a) => (b) => (c) => (d) => { return a * b * c * d; }

Collapse
 
pris_stratton profile image
pris stratton

Nice article 😀

I found that learning the basics of Haskell was a great way to learn FP concepts. I also cannot recommend Grokking Simplicity by Eric Normand enough - great book on practical FP.

 
pengeszikra profile image
Peter Vivo

How long time ago don't use debugging with stack trace. My main method is functional test plus state debugg.

 
pengeszikra profile image
Peter Vivo

Sorry, my english isn't so fine. Any way I don't remember when I saw stack trace, that why I don't care about function name mostly when I use currying.