# Higher-Order Functions

A higher-order function is a function that accepts another function as a parameter or returns a function as its return type. The easiest way to understand this is by realizing that functions can be treated just like any other piece of data.

In languages that support higher-order functions, much like you would with a `String` or `Integer`, you can pass functions as parameters, store them, and return them.

# Anonymous Functions

Before exploring higher-order functions, it is first important to cover anonymous functions, which are often used alongside higher-order functions.

An anonymous function, or lambda, is simply a function that was declared without any named identifier to refer to it. They can still be stored in variables and therefore can still be named within the code, but the function itself is declared without a name attached.

For example, in Java, a simple anonymous function looks like this:

`x -> x + 1`

The input of this function is `x`, and the output is `x + 1`.

Syntax for anonymous functions varies slightly across languages, but it is typically written in the form of (inputs) → (output).

Anonymous functions are often used because they avoid the boilerplate code associated with formally declaring them as named functions. So, for simple functions that may not be used in more than one place, such as the above, it may be more appropriate to use an anonymous function.

## Example

Now, we will go into a very basic example of a higher-order function that uses anonymous functions. This example uses Python, where the syntax for anonymous functions is `lambda (inputs): (output)`.

`def add_n(n):    return lambda x: x + n`

This example takes a number `n` and returns a function that adds `n` to the input.

So, if we wanted to add 1 + 2, we could do that by calling `add_n(2)(1)`. The first call, `add_n(2)`, returns a function that adds 2 to its input, and the second call `(1)` uses that function to add 2 to 1.

# Common Higher-Order Functions

There are a few specific higher-order functions that are essential to understanding modern codebases. These primarily deal with iterating or summing up lists of data.

They provide a much cleaner way to deal with common list operations, saving you from having to create a lot of helper code to do basic list operations. This creates code that is more explicit in its intention.

For these examples, I will use Python-ish code throughout. Most other modern languages, such as Java and JavaScript, also have these features.

## Map

The `map` operation allows you to apply a function to each element of a list, and then return a new list with those new values.

Without `map`, your code to do this would look like this:

`new_list = []old_list = [...]for e in old_list:    new_list.append(some_function(e))return new_list`

Here, our goal was to apply `some_function` to every element of `old_list`. At the end of this loop, `new_list` now contains this result.

With `map`, we can do this in a much cleaner way.

The `map` function takes in a function and a list, and returns a new list with that function applied to every element of the list. It is used as follows:

`old_list = [...]return map(some_function, old_list)`

So, if `old_list = [1, 2, 3]` and `some_function = lambda x: x + 1` , the returned value would be `[2, 3, 4]` .

## Filter

The `filter` operation allows you to return the elements of a list that meet a condition.

Without filter, your code to accomplish this would look like this:

`new_list = []old_list = [...]for e in old_list:    if some_function(e):        new_list.append(e)return new_list`

Here, we want to return the subset of elements in `old_list` for which `some_function` returns `True`.

With filter, we can, again, do this in a much cleaner way. Filter takes in a function and a list, and returns a new list with only the elements in that list for which the function returns `True`.

We use filter as follows:

`old_list = [...]return filter(some_function, old_list)`

So, if `old_list = [1, 2, 3]` and `some_function = lambda x: x == 2` , then the return value of this would be `` .

## Reduce

The `reduce` operation allows you to calculate a single value based on a function used to combine all of the elements of the list. For example, this could be adding all of the elements of a list to find the list’s sum.

Without `reduce`, your code would look like this:

`accumulator = 0old_list = [...]for e in old_list:    accumulator += ereturn accumulator`

The accumulator variable is initialized with a value (`0`, in this case), and holds the accumulated result of applying a function to the accumulator and each list element.

In this case, the function is `lambda accumulator, e: accumulator + e`.

So, for a given function `f`, the reduce operation is equivalent to calling `f(...(f(f(initial, list), list),...), list[n])`.

For example, say `old_list = [1, 2, 3, 4]` and we use the function `lambda accumulator, e: accumulator + e` with an initial value of `0`.

Then, the value of our reduce operation would be `((((0 + 1) + 2) + 3) + 4)`, which is exactly the same result as the snippet above.

We can use `reduce` as follows:

`old_list = [...]initial = 0return reduce(lambda acc, e: acc + e, old_list, initial)`

(Note that Python’s actual `reduce` function does not take an initial value as a parameter — it just uses the first value of the list as the initial value. The above syntax is more generalized to what other languages do.)

Written by