The single most important topic in functional programming is to understand what a function is. Inherently, a function is a way to map the input value of some type to output value of another type. To put it in other words, you give your function a problem, and it returns a solution.

In mathematics, you may have stumbled upon the formal definition of a function.

$f: A \to B$

This is essentially the same as written above. We define a function f accepting a value of A and returning a value of B. Note that A and B could be of the same type, but for the sake of this example, we keep them separate.

In programming, problems are bound to grow more difficult over time, and thus solutions grow more complex. Typically, the larger the problem, the larger our function grows in size. Following the principles of clean code – single-responsibility principle, to be accurate – we need to keep in mind that functions should do only one thing and do it well.

So, what possibly could help us? Add more functions!

When solving a large problem, the important approach is to divide and conquer. First, break the problem into small parts (divide) and then solve each of them one by one (conquer). We can use the concept of higher-order functions to achieve this.

## Anatomy of a Higher-Order Function

A higher-order function is defined to have either of the following two properties:

1. It takes one or more functions as its arguments
2. It returns another function (a closure)

React developers know that for example, the useState hook for managing component state is a higher-order function since it returns a function used for updating the state.

const App = () => {
const [counter, setCounter] = useState(0)
// typeof setCounter === 'function'
}

At first, higher-order functions seemed to me like an overcomplicated problem-solving tool. Why not write a single function and call other functions from inside? Truthfully speaking, I thought as much about object-oriented programming before grasping how different design patterns improve the code.

This was my mind before I understood the value of declarative programming over imperative. In declarative programming, you define what things are, whereas, in imperative programming, you define what things do.

Solving problems in a declarative way is a perfect demonstration of divide and conquer. Let’s take an example.

Assume we are given a user password for validation. Our function should return true if the password is valid, and false otherwise. We have received the following requirements for validating passwords:

• password must contain 12 or more characters
• password must contain at least one uppercase and one lowercase character
• password must contain at least one number

What an easy task, you might think. Write a function with a couple of conditional blocks and after having run through all of them return the intended result. Let’s grab a keyboard and start defining our function.

This is perfectly fine for a lax validation. However, what if requirements keep on coming, and you need to add more and more conditionals into your function? Your function could quickly grow to a convoluted, unmaintainable, and unreadable mess.

One solution is to define each validator as a function and pass it as an argument. The example below is in Javascript.

/** Helper for printing the validator warnings */
const warn = msg => {
console.warn('Invalid:', msg)
return false
}

/** Validators */
const longEnough = (password, minLength = 12) => password.length >= minLength || warn(Password should contain \${minLength} or more characters.)

/** Higher-order function to run the given validators */

const validator = validate('SUP3RsECREtP4ssW0rd')
console.log(validator(
longEnough,
hasUpperCase,
hasLowerCase,
hasNumbers,
)) // => true

Breaking this down you can see that longEnough, hasUpperCase, hasLowerCase, and hasNumbers are each a closure passed to the validator function. Using variadic arguments – known as the spread operator (...) in Javascript – we can pass any number of validators and our code takes care of the rest.

The Array.prototype.every function returns true if the array satisfies all the conditions passed so here we pass predicate (boolean) functions as conditions.

Another sweet aspect of higher-order functions is the ability to curry your functions. Here we pass our password to the validate function which returns a new function accepting the validators as arguments. Doing this, we don’t have to pass the password again for each of the validator functions. This makes the code easier to read again.

Perhaps your head is spinning fast right now, so let’s write the validate function without the ES6 arrow notation to examine it further.

function validate(password) {
return function(...fns) {
return fns.every(function(fn) {
}
After removing the arrows, we have a function satisfying both pre-conditions of being a higher-order function. In my opinion, arrow functions have made writing especially Javascript way more succinct since we can write all of this in one line and without using a single return statement. No more nested code, also known as hadouken code.