Scala | Lambdas and Higher Order Functions

A key strength of Scala is its support for functional programming. While things like anonymous functions, lambda expressions, and higher order functions are key components of functional programming, they are often confusing concepts for newcomers. In this tutorial, we explain the difference between these concepts along with basic examples of both anonymous and higher order functions in Scala.

What is an anonymous function?

An anonymous function is a function without a formal definition. Just like regular functions, anonymous functions accept parameters and can return values. The key difference is how they are used. Anonymous functions aren't defined and used in multiple places. Instead, anonymous functions are passed in as arguments to higher order functions and are typically used in just one place.

Example of an anonymous function

(a: Int) => a*2

The above is a basic example of an anonymous function. Notice how it accepts a single parameter a of type Int and returns the result of a*2.

What is a higher order function?

A higher order function accepts anonymous functions as arguments and/or returns anonymous functions.

Example of higher order function

def doubleAndPrint(a: Int, f: Int => Int) = {
  val result = f(a)
  System.out.println("the value is now " + result)
}

doubleAndPrint(5, a => a*2 )
//prints "the value is now 10"

In the above example, we first define a method doubleAndPrint() accepting two arguments. The first argument a is of type Int. The second argument f is a lambda expression. A lambda expression is simply a reference to an anonymous function. In fact, you will often hear lambdas and anonymous functions used interchangeably.

Our doubleAndPrint method is considered a higher order function because it accepts an anonymous function as an argument. When we invoke the method, we pass in the same anonymous function a => a*2. You'll notice that we don't declare a type for the anonymous function's single argument a. This is because our higher order function specifies the argument type and return value via the lambda expression Int => Int.

Why use anonymous functions with Scala?

Anonymous functions provide several benefits including:

Decoupling

With anonymous functions, you can more clearly separate different pieces of functionality. A higher order function can accept an anonymous function without knowing the internals of how that function works. This allows you flexibility in how you compute arguments that are passed in as higher order functions are only concerned with argument and return types.

Convenience

Anonymous functions add convenience to your code base when you only need them for a single purpose. Instead of formally defining a separate method, you can write a single function that is used specifically for the higher order function you are plugging it into.

Conclusion

An anonymous function is simply a function without a formal definition. Anonymous functions are used as arguments for higher order functions. Higher order functions accept anonymous functions as arguments and/or return anonymous functions. Lambda expressions are simply references to anonymous functions and are often used interchangeably when describing anonymous functions. Anonymous functions are useful as they provide convenience and better organize app logic.

Your thoughts?