Higher oder functions are one of the main ideas of functional programming, but many developers don't get them, it also took me a few months, so I will try to explain them. Hopefully my explanation will be so easy that a 5 year old understands them, which I doubt, haha.
First, lets talk about functions. They are things you can put things into and other things come out of it and in between they do something with the things you put in.
The things you put into them are called arguments, the things that come out are called return values. In many programming languages, functions can only have one return value, in some they can even just have one argument.
What makes a regular function a higher-order function?
If you have a function that takes a function in one or more of their arguments and/or returns one or more functions as their return values, you have a higher-order function.
Not more not less.
5 year mode off
Extra 1: Wrappers
Often other functions that work with functions are called wrapper. While wrappers often work like the thing you wrapped with them. Higher-order functions are more general.
function timesTen(x) { return x * 10; }
// a wrapper
// works always with the same function it wraps
function timesTenPlusTen(x) { return timesTen(x) + 10; }
timesTenPlusTen(10);
// a higher order function
// works with the function it takes as an argument
function doXPlusTen(f, x) { return f(x) + 10; }
doXPlusTen(timesTen, x);
Extra 2: One Argument Functions
I talked about languages where functions only can take one argument, so how does this work?
Well, they can return a function and these returned functions they create can access the one argument of their parent.
function times(x) {
return function(y) {
return x * y;
};
}
// in JavaScript it would be used like that:
let f = times(10); // returns the second function and saves it in f
f(10); // executes the second function that has access to x AND y
// in short
times(10)(10);
This is also called currying and often these languages have short syntax for function creation.
function f(x) { return x * x; }
// works like
let f = x => x * x;
// so our example from above could be written as
let times = x => y => x * y;
// still works as before
times(10)(10);
Why?
As you saw, some languages won't even work without this concept, because of the one-argument rule, but the most basic usage I encounter every day are functions that let you add other functions as event listeners. So the addEventListener
functions you may know from languages like JavaScript are higher-order functions, because one of their arguments has to be a function.
function doSomething() { alert("Loaded!"); }
window.addEventListener('load', doSomething);