First-Class and Higher-Order Functions

19 Jan 2022

To First-Class and Beyond!

In this article, I’m going to discuss the basics of first-class and higher-order functions and why you should consider using them if you are not already.

You can use first-class and higher-order functions in a variety of programming languages, but I will be using JavaScript for the examples in this article.

The Basics

For those not familiar with the concept, objects are considered first-class when the programming language treats them like a variable. In the case of functions, this means that a function can be stored in a variable, returned from another function, etc. Let’s look at an example (JSFiddle):

const firstClass = function() {
  console.log("Hello World!");
}
firstClass(); // prints "Hello World!"

Higher-order functions are functions that take another function as an argument, return a function, or both. This means that higher-order functions are only possible if the programming language supports first-class objects. Let’s look at an example (JSFiddle):

const higherOrder = function() {
  return function() {
    console.log("Hello World!");
  }
}
higherOrder()(); // prints "Hello World!"

Why Should I Use This?

First-class and higher-order functions sound confusing at first, so why bother? Once you understand the basics and you get familiar with thinking about problems from a different perspective, they can be a powerful tool that both saves time and reduces the complexity of your code. To demonstrate these benefits, let’s consider an application that applies filters to an image. Without using first-class functions, your application might look something like this:

...
image = grayScale(image);
image = sharpen(image);
...

This does not look too bad with only a few filters, but what if you had a few hundred filters or you want to dynamically change which filters are applied to an image? You could create a huge list of booleans, if statements and functions, and somehow manage to keep track of them all, but what if there was a better way? Enter first-class functions. With first-class functions, your application might look something like this:

...
let filters = [
  grayScale,
  sharpen
];

for (let i = 0; i < filters.length; i++) {
  image = filters[i](image);
}
...

Simply add/remove functions from the filters array and you’ve changed which filters are applied! Pretty nifty, huh?

Conclusion

The example above is only scratching the surface of what you can do with first-class and higher-order functions. I find myself passing functions as parameters to other functions most often, probably due to map(), but I try to use first-class and higher-order functions in other ways as often as possible for the aforementioned benefits.