Higher-Order Functions are functions that can take one or more functions as arguments, these functions may also return functions.  in other words they take one or more functions as arguments (i.e. procedural parameters), and/or returns a function as their results. Functions that are not higher-order functions are called first-order functions.

For programmers, the first instances of Higher-Order Functions were seen in Functional programming languages like Erlang and were not originally found in so-called “pure”  programming languages such as the older version of Java.

These days, however, we increasingly see Higher-Order Functions used in so-called “mixed” programming languages that introduce functional elements to previously non-functional language contexts.

This article will focus on using Higher-Order functions in programming, for the theory see my article on lambda calculus.

To elaborate on this further, we pass in functions to higher-order functions in the form of lambda-expressions which are called lambdas in python and closures in Swift (in Swift functions are closures). Higher-Order functions could be replaceable with first-order functions with recursion, yet the use of higher-order functions can be more expressive, and it can also reduce the need for recursion in our code (Ref#: J). Whilst an exploration of the lambda calculus will give you more of a theoretical understanding of this topic, this article will instead focus on use cases in programming languages (Ref#: H). 

Higher-Order Functions can also be used to create “partial applications” of functions, or an application of a function to a particular subset of its arguments (Ref#: J).

Functions which take Functions as Arguments

Here is a Python example of using a function which takes a function as an argument:

Function Composition

Higher-Order Functions allow us to compose functions, this allows us to build together smaller functions to make larger functions. In other words composition “takes two functions as input and returns (evaluates to) a function which is their composition” (Ref#: J).

In Python this might look like:

To achieve function composition in swift, it’s easier if we add something extra to the language to help us, like this:

Map, Filter, and Reduce

Map, Filter, and Reduce (and compactMap / flatMap) are pre-defined higher-order functions which can be really useful tools for working with collections (such as lists and other collection types like the “ArrayList” in Java or “Array” in Swift). There are quite a few programming languages that now have these built-in, including JavaScript, Python, Java 8 (which introduced language-level support for Lambda Expressions), and indeed Swift.

This provision by libraries of pre-defined functions like map is important to distinguish from the option of defining one’s own higher-order functions, but to do this the language needs support for the functional elements covered above.

Let’s explore what these functions are used for, and the benefits of each. The functions we shall talk about facilitate a so-called functional approach to programming.

Map

Use map to loop over a collection and apply the same operation to each element in the collection.” 

To explore the benefits of map, let us look at some examples. As we mentioned in the intro, the way we often use map is through the use of lambdas (aka lambda abstractions/blocks/closures/anonymous functions). 

Looking at a real-world example which could be indeed useful, imagine you have a weather app: the source temperatures are in Fahrenheit but you want the app to work for European customers who expect their temperatures to be displayed to them in Celsius. One can apply map, using Python, to this situation as follows:

This would output temperatures as:

[37.77777777777778, 48.88888888888889, 32.22222222222222]

Similarly, in Swift you might do something like:

Whilst we might choose to round these down for display, we now have equivalent values in the alternative representational format. Essentially the map function has taken an anonymous function as an argument and it has proceeded to iterate over the input values and apply this function to each, in turn, creating then the output.

Similarly, we can also do something like this in Swift to get the square values for an array of values:

CompactMap

The keyword .compactMap is used in Swift is used to flatten a collection of collections, and it can even deal with optionals and thus useful where a particular sub-collection could be nil. Or in other words, it “returns an array containing the non-nil results of calling the given transformation with each element of this sequence”.

Example

Sources: https://useyourloaf.com/blog/replacing-flatmap-with-compactmap/     

https://www.avanderlee.com/swift/compactmap-flatmap-differences-explained/

Filter

Use filter to loop over a collection and return an Array containing only those elements that match an include condition.

Let’s explore how we achieve this in code using Swift:

Above, we look to create an array with the non-even numbers filters out. Part 1 shows the naive way of doing this using a for loop, whereas part 2 shows the much simpler syntax of using filter. We pass a closure (an anonymous function) to the filter function, and when doing this we use the placeholder “$0” to denote each element and we use the modulus operator (“%”) to check whether each int is divisible by 2, if so it’s kept. What’s going on under the hood here is that the closure is returning a boolean (true/false) value and where this is true the element (denoted by $0) is kept in, and where false it is left out.

We can equally do something similar in Python:

Now we can also do something (kinda) similar in Java 8 using streams:

Reduce

The reduce function returns the result of combining the elements of the sequence using the given closure.

Let look at implementing reduce in Swift:

Above we have combined all the numbers in an array of Ints to a single number, but instead of using a loop to do this or a static expression, we have used reduce.

In Python 3 (as opposed to Python 2) we now need to import this from the functools module to use the reduce function, as the language creator has said that using reduce for combining items in a collection is not his preferred syntax, as he believed that doing it explicitly in code is more readable, and thus that using higher-order function based solution is unnecessary.

Sorted

One extra build-in higher-order function in Swift is called “sorted” and is used to sort arrays in very few lines of code, or just a single line, like this:

In the above we can see that we pass our sorting rule in as a closure such as {$0 < $1}, and swift also gives some interesting short-hand options for our sorting rules such as in section 5 above where we just say sorted(by: <) and Swift will actually infer what we mean.

Conclusion

In conclusion, we have seen what higher-order functions are and how we could use these in mixed programming languages. The use of higher-order functions where this is not the only way of coding a solution is controversial as some see it as unnecessary, but yet it’s good to know about this stuff and be able to read code using higher-order functions, and code solutions this way where appropriate.

References

A: [Socratica]. (2017, Sep 18). Map, Filter, and Reduce Functions || Python Tutorial || Learn Python Programming. Retrieved from”https://goo.gl/hgox2X”.

B:  https://www.sitepoint.com/java-8-streams-filter-map-reduce/

C:  http://web.mit.edu/6.005/www/fa15/classes/25-map-filter-reduce/

D:  http://www.java67.com/2016/09/map-reduce-example-java8.html

E: https://useyourloaf.com/blog/swift-guide-to-map-filter-reduce/

F: https://www.youtube.com/watch?v=fbYMaJciMZY

G: https://www.tutorialspoint.com/java8/java8_streams.htm

H: https://en.wikipedia.org/wiki/Higher-order_function

I: https://clojure.org/guides/higher_order_functions

J: Craig, I. (2001). The Interpretation of Object-Oriented Programming Languages.

K: Cesarini, F. & Thompson, S. (2009). Erlang Programming: A Concurrent Approach to Software Development. O’Reilly Media, CA, USA.

L: 1.6 Higher-Order Functions. Retrived from: http://composingprograms.com/pages/16-higher-order-functions.html

M: Higher Order Functions and Decorators. Retrieved from: https://www.hackerearth.com/practice/python/functional-programming/higher-order-functions-and-decorators/tutorial/

N: Higher Order Functions In Xcode 8 (Swift 3) – Part 1/2. https://www.youtube.com/watch?v=p5-UFGO5e_0

O: Non-escaping error when implementing Church Numerals in Swift 3. Retrieved from: https://stackoverflow.com/questions/39810705/non-escaping-error-when-implementing-church-numerals-in-swift-3

P*: Functional Snippet #2: Function Composition. Retrieved from: https://www.objc.io/blog/2014/10/13/functional-snippet-2-function-composition/

Q: https://www.python-course.eu/python3_lambda.php

R: LAMBDA Functions: Powerful And Elegant Abstractions. Retrieved from: https://www.youtube.com/watch?v=OLH3L285EiY

S: https://www.youtube.com/watch?v=wB-bi8_rSLs

last updated: 3rd September 2019

Last modified: June 1, 2022

Author

Comments

Comments