How to use function literals (anonymous functions) in Scala

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 9.1, “How to use function literals (anonymous functions) in Scala.”

Problem

You want to use an anonymous function in Scala — also known as a function literal — so you can pass it into a method that takes a function, or to assign it to a variable.

Solution

Given this List:

val x = List.range(1, 10)

you can pass an anonymous function to the List’s filter method to create a new List that contains only even numbers:

val evens = x.filter((i: Int) => i % 2 == 0)

The Scala REPL demonstrates that this expression indeed yields a new List of even numbers:

scala> val evens = x.filter((i: Int) => i % 2 == 0)
evens: List[Int] = List(2, 4, 6, 8)

In this solution, the following code is a function literal (also known as an anonymous function):

(i: Int) => i % 2 == 0

Although that code works, it shows the most explicit form for defining a function literal. Thanks to several Scala shortcuts, the expression can be simplified to this:

val evens = x.filter(_ % 2 == 0)

In the REPL, you see that this returns the same result:

scala> val evens = x.filter(_ % 2 == 0)
evens: List[Int] = List(2, 4, 6, 8)

Discussion

In this example, the original function literal consists of the following code:

(i: Int) => i % 2 == 0

When examining this code, it helps to think of the => symbol as a transformer, because the expression transforms the parameter list on the left side of the symbol (an Int named i) into a new result using the algorithm on the right side of the symbol (in this case, an expression that results in a Boolean).

As mentioned, this example shows the long form for defining an anonymous function, which can be simplified in several different ways. The first example shows the most explicit form:

val evens = x.filter((i: Int) => i % 2 == 0)

Because the Scala compiler can infer from the expression that i is an Int, the Int declaration can be dropped off:

val evens = x.filter(i => i % 2 == 0)

Because Scala lets you use the _ wildcard instead of a variable name when the parameter appears only once in your function, this code can be simplified even more:

val evens = x.filter(_ % 2 == 0)

In other examples, you can simplify your anonymous functions further. For instance, beginning with the most explicit form, you can print each element in the list using this anonymous function with the foreach method:

x.foreach((i:Int) => println(i))

As before, the Int declaration isn’t required:

x.foreach((i) => println(i))

Because there is only one argument, the parentheses around the i parameter aren’t needed:

x.foreach(i => println(i))

Because i is used only once in the body of the function, the expression can be further simplified with the _ wildcard:

x.foreach(println(_))

Finally, if a function literal consists of one statement that takes a single argument, you need not explicitly name and specify the argument, so the statement can finally be reduced to this:

x.foreach(println)

Expression-Oriented Programming (EOP)

In the print version of the Scala Cookbook, this discussion of Expression-Oriented Programming was given in the introduction to Chapter 9. In this web version of the Scala Cookbook I have included it here in Recipe 9.1.

As a language that supports functional programming, Scala encourages an expression- oriented programming (EOP) model. Simply put, in EOP, every statement (expression) yields a value. This paradigm can be as obvious as an if/else statement returning a value:

val greater = if (a > b) a else b

It can also be as surprising as a try/catch statement returning a value:

val result = try {
    aString.toInt
} catch {
    case _ => 0
}

Although EOP is casually demonstrated in many examples in this book, it’s helpful to be consciously aware of this way of thinking in the recipes here in Chapter 9.

The Scala Cookbook

This tutorial is sponsored by the Scala Cookbook, which I wrote for O’Reilly:

You can find the Scala Cookbook at these locations:

Add new comment

The content of this field is kept private and will not be shown publicly.

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.