DEV Community

Juan Cruz Martinez
Juan Cruz Martinez

Posted on • Originally published at livecodestream.dev on

What Is a Higher Order Function?

Image by the author

When we think of functions in any programming language, we think of reusable code abstracted into a separate block that performs specific tasks. Such functions can take inputs, process them and provide output according to the instructions coded in the function.

Functions normally receive values as inputs, such as numbers, strings, and references or copies of objects and lists, and would optionally return values in those types.

But hold on, what if, for example, we are implementing a timer function that, after X seconds passed, will execute a given piece of code? Could such a timer function have another function as its input?


What are higher-order functions?

In computer science, higher-order functions (a key element of functional programming) are functions that can take other functions as inputs or return them as outputs. They, therefore, allow us to create abstractions over existing functionality and compose new functionality out of existing ones.

As a big fan of functional programming, I love higher-order functions. They are useful for writing more readable and easier-to-maintain code. And its a paradigm I often use when working with JavaScript/TypeScript, especially when working with React. Though I gotta admit, I haven't used that much of it when working with Python.

Higher-order functions are great, but...


Why would I use higher-order functions?

Higher-order functions are useful for writing code that is more general, extensible, and reusable. You can use them to create abstractions over existing functionality and compose new functionality out of existing ones. Additionally, they let you control scope, simplify callbacks (like promises), eliminate unnecessary code duplication, and write cleaner code by separating the logical flow from the implementation details.

Ever worked with filter, map, forEach methods in JavaScript? Those are excellent examples of higher-order JavaScript functions.


Writing your first higher-order functions

Let's start simply by building two different higher-order functions. The first one would take a function as input, while the second example would return a function. Next, we'll write our own definitions for some of the most popular higher-order functions, some of which we have already named before.

All code samples are provided in Python and JavaScript as those are the language I'm most familiar with, but if you want to help, you can send me these same functions in other programming languages, and I'll gladly add them here.

Taking a function as an argument

To start, let’s build a very simple function, doOperation which takes 3 arguments:

  • The function operation
  • number1
  • number2

Additionally, we will create an operation called sumBothNumbers which will simply return the sum of 2 numbers.

The idea is that doOperation would run the given operation function to both numbers and return the final result. The operation input can by any function that takes two numbers and performs a calculation, such as calculating the sum of both numbers.

Python:

def doOperation(operation, number1, number2):
    return operation(number1, number2)

def sumBothNumbers(number1, number2):
    return number1 + number2

doOperation(sumBothNumbers, 3, 5)

------------
Output
------------
8
Enter fullscreen mode Exit fullscreen mode

Javascript:

function doOperation(operation, number1, number2) {
    return operation(number1, number2)
}

function sumBothNumbers(number1, number2) {
    return number1 + number2
}

doOperation(sumBothNumbers, 3, 5)

------------
Output
------------
8
Enter fullscreen mode Exit fullscreen mode

Returning a function

Next, we will build a higher-order function that returns a function. Our function will be called multiplyBy and it will take a number as an argument and return a function that will multiply its input by that number.

Python:

def multiplyBy(multiplier):
    def result(num):
        return num * multiplier
    return result

multiplyByThree = multiplyBy(3)
multiplyByThree(4)

------------
Output
------------
12
Enter fullscreen mode Exit fullscreen mode

JavaScript:

function multiplyBy(multiplier) {
    return function result(num) {
        return num * multiplier
    }
}

multiplyByThree = multiplyBy(3)
multiplyByThree(4)

------------
Output
------------
12
Enter fullscreen mode Exit fullscreen mode

Building Filter(), Map() and Reduce()

We are getting pros at working with higher-order functions, and though it may still take some practice to find out good opportunities to use them, you are in great shape to work on some more complex implementations.

To level up our higher-order functions skills, we will write the code for some of the most popular array methods in the functional programming paradigm.

filter() aka filtering()

The filtering function will have 2 parameters, an array and a test function. It will return a new array with all the elements that pass the test.

Python:

def filtering(arr, test):
    passed = []
    for element in arr:
        if (test(element)):
            passed.append(element)
    return passed

def isSuperNumber(num):
    return num >= 10

filtering([1, 5, 11, 3, 22], isSuperNumber)

------------
Output
------------
[11, 22]
Enter fullscreen mode Exit fullscreen mode

JavaScript:

function filtering(arr, test) {
    const passed = []
    for (let element of arr) {
        if (test(element)) {
            passed.push(element)
        }
    }
    return passed
}

function isSuperNumber(num) {
    return num >= 10
}

filtering([1, 5, 11, 3, 22], isSuperNumber)

------------
Output
------------
> (2) [11, 22]
Enter fullscreen mode Exit fullscreen mode

map() aka mapping()

The function mapping will take 2 parameters: an array and a transform function, and it will return a new transformed array where each item is the result of the transform function called over each element of the original array.

Python:

def mapping(arr, transform):
    mapped = []
    for element in arr:
        mapped.append(transform(element))
    return mapped

def addTwo(num):
    return num+2

mapping([1, 2, 3], addTwo)

------------
Output
------------
[3, 4, 5]
Enter fullscreen mode Exit fullscreen mode

JavaScript:

function mapping(arr, transform) {
    const mapped = []
    for (let element of arr) {
        mapped.push(transform(element))
    }
    return mapped
}

function addTwo(num) {
    return num + 2
}

mapping([1, 2, 3], addTwo)

------------
Output
------------
> (3) [3, 4, 5]
Enter fullscreen mode Exit fullscreen mode

reduce() aka reducing()

The function reducing will take 3 parameters: a reducer function, an initial value for the accumulator and an array. For each item in the array, the reducer function is called, passing it to the accumulator and the current array element. The return value is assigned to the accumulator. After reducing all the items in the list, the accumulated value is returned.

Python:

def reducing(reducer, initial, arr):
    acc = initial
    for element in arr:
        acc = reducer(acc, element)
    return acc

def accum(acc, curr):
    return acc + curr

reducing(accum, 0, [1, 2, 3])

------------
Output
------------
6
Enter fullscreen mode Exit fullscreen mode

JavaScript:

function reducing(reducer, initial, arr) {
    let acc = initial
    for (element of arr) {
        acc = reducer(acc, element)
    }
    return acc
}

function accum(acc, curr) {
    return acc + curr
}

reducing(accum, 0, [1, 2, 3])

------------
Output
------------
6
Enter fullscreen mode Exit fullscreen mode

FAQs

Why are they called higher-order functions?

A higher-order function takes its name because they typically act on or return functions from a higher order (or level) of abstraction.

What is functional programming?

Functional programming is a programming paradigm focusing on writing programs as a series of functions rather than code with a mutable state. It emphasizes using higher-order functions and immutable data structures to create modular, maintainable code.

Are higher-order functions a common topic in interviews?

Yes, higher-order functions are a common topic in software engineering interviews, it depends on the programming role and language, but generally speaking, it is good to know it. They are an important aspect of functional programming and writing code with scalability and reusability in mind. Knowing how to write and use higher-order functions is essential for software engineers who want to work on modern web or mobile applications.


Conclusion

Next time when you get to that interview, or simply you see a pattern where a function is either returned or taken as a parameter, you will know we are dealing with higher-order functions.

Today for the first time, I’ve introduced an article covering more than one language. If you find it a great way to showcase and compare them, or if you think it was a terrible idea, please let me know in the comments or by Twitter. I’d love to hear your ideas.

Thanks so much for reading!


Newsletter

Subscribe to my weekly newsletter for developers and builders and get a weekly email with relevant content.

Top comments (0)