Reducing code duplication

One benefit of higher-order functions is they enable you to create control abstractions that allow you to reduce code duplication.

First, you add a facility to search for files whose names end in a particular string. This would enable your users to find, for example, all files with a “.scala” extension. You could provide such an API by defining a public filesEnding method inside a singleton object like this:

object FileMatcher {
  private def filesHere = (new".")).listFiles
  def filesEnding(query: String) =
    for (file <- filesHere; if file.getName.endsWith(query))
      yield file
  • The filesEnding method obtains the list of all files in the current direc- tory using the private helper method filesHere, then filters them based on whether each file name ends with the user-specified query.
  • Given filesHere is private, the filesEnding method is the only accessible method defined in FileMatcher, the API you provide to your users.

Experienced programmers will notice all of this repetition and wonder if it can be factored into a common helper function. Doing it the obvious way does not work, however. You would like to be able to do the following:

// WARN Pseudocode
def filesMatching(query: String, method) =
  for (file <- filesHere; if file.getName.method(query))
    yield file

This approach would work in some dynamic languages, but Scala does not allow pasting together code at runtime like this.

Function values provide an answer. While you cannot pass around a method name as a value, you can get the same effect by passing around a function value that calls the method for you.

In this case, you could add a matcher parameter to the method whose sole purpose is to check a file name against a query:

def filesMatching(query: String, matcher: (String, String) => Boolean) = {
  for (file <- filesHere; if matcher(file.getName, query))
    yield file
  • In this version of the method, the if clause now uses matcher to check the file name against the query.
  • Precisely what this check does depends on what is specified as the matcher.

Given this new filesMatching helper method, you can simplify the three searching methods by having them call the helper method, passing in an appropriate function:

def filesEnding(query: String) =
  filesMatching(query, _.endsWith(_))
def filesContaining(query: String) =
  filesMatching(query, _.contains(_))
def filesRegex(query: String) =
  filesMatching(query, _.matches(_))

The function literals shown in this example use the placeholder syntax, introduced in the previous chapter, which may not as yet feel very natural to you. So here’s a clarification of how placeholders are used: The function literal _.endsWith(_), used in the filesEnding method, means the same thing as:

(fileName: String, query: String) => fileName.endsWith(query)

The first underscore is a placeholder for the first parameter, the file name, and the second underscore a placeholder for the second parameter, the query string.

In Java, for example, you could create an interface containing a method that takes one String and returns a Boolean, then create and pass anonymous inner class instances that implement this interface to filesMatching. Although this approach would remove the code duplication you are trying to eliminate, it would, at the same time, add as much or more new code. Thus the benefit is not worth the cost, and you may as well live with the duplication.

object FileMatcher {
  private def filesHere = (new".")).listFiles
  private def filesMatching(matcher: String => Boolean) =
    for (file <- filesHere; if matcher(file.getName))
      yield file
  def filesEnding(query: String) =
  def filesContaining(query: String) =
  def filesRegex(query: String) =

Using closures to reduce code duplication

By contrast, the function literal _.endsWith(query), used in the most recent example, contains one bound variable, the argument represented by the underscore, and one free variable named query. It is only because Scala supports closures that you were able to remove the query parameter from filesMatching in the most recent example, thereby simplifying the code even further.

Simplifying client code

The previous example demonstrated that higher-order functions can help re- duce code duplication as you implement an API. Another important use of higher-order functions is to put them in an API itself to make client code more concise.

Consider exists, a method that determines whether a passed value is contained in a collection.

def containsNeg(nums: List[Int]): Boolean = {
  var exists = false
  for (num <- nums)
    if (num < 0)
      exists = true

A more concise way to define the method, though, is by calling the higher-order function exists on the passed List, like this:

def containsNeg(nums: List[Int]) = nums.exists(_ < 0)
  • The exists method represents a control abstraction. It is a special-purpose looping construct provided by the Scala library.
  • The exists method provides a similar benefit, but because exists is public in Scala’s collections API.


A curried function is applied to multiple argument lists, instead of just one.

def plainOldSum(x: Int, y: Int) = x + y
plainOldSum(1, 2)

Defining and invoking a “plain old” function

By contrast, below shows a similar function that’s curried. Instead of one list of two Int parameters, you apply this function to two lists of one Int parameter each.

def curriedSum(x: Int)(y: Int) = x + y

Defining and invoking a curried function

  • What’s happening here is that when you invoke curriedSum, you actually get two traditional function invocations back to back.
  • The first function invocation takes a single Int parameter named x, and returns a function value for the second function.
  • This second function takes the Int parameter y.

Here’s a function named first that does in spirit what the first traditional function invocation of curriedSum would do:

def first(x: Int) = (y: Int) => x + y

Applying the first function to 1—in other words, invoking the first function and passing in 1—yields the second function. Applying the second function to 2 yields the result.

val second = first(1)

res: Int = 3

These first and second functions are just an illustration of the currying process.

These first and second functions are just an illustration of the currying process. They are not directly connected to the curriedSum function. Nevertheless, there is a way to get an actual reference to curriedSum’s “second” function. You can use the placeholder notation to use curriedSum in a partially applied function expression, like this:

val onePlus = curriedSum(1)_

res: Int = 3

Writing new control structures

Any time you find a control pattern repeated in multiple parts of your code, you should think about implementing it as a new control structure.

def twice(op: Double => Double, x: Double) = op(op(x))

twice(_ + 1, 5)
res: Double = 7.0
def withPrintWriter(file: File, op: PrintWriter => Unit) = {
  val writer = new PrintWriter(file)
  try {
  } finally {

Given such a method, you can use it like this:

  new File("date.txt"),
  writer => writer.println(new java.util.Date)

The advantage of using this method is that it’s withPrintWriter, not user code, that assures the file is closed at the end.

So it’s impossible to forget to close the file. This technique is called the loan pattern, because a control-abstraction function, such as withPrintWriter, opens a resource and “loans” it to a function.

When the function completes, it signals that it no longer needs the “borrowed” resource. The resource is then closed in a finally block, to ensure it is indeed closed, regardless of whether the function completes by returning normally or throw- ing an exception.

def withPrintWriter(file: File)(op: PrintWriter => Unit) = {
  val writer = new PrintWriter(file)
  try {
  } finally {

Using the loan pattern to write to a file

val file = new File("date.txt")
withPrintWriter(file) { writer =>
  writer.println(new java.util.Date)

In this example, the first argument list, which contains one File argument, is written surrounded by parentheses. The second argument list, which contains one function argument, is surrounded by curly braces.

By-name parameters

Scala provides by-name parameters. Without using by-name parameters, you could write myAssert like this:

var assertionsEnabled = true
def myAssert(predicate: () => Boolean) =
  if (assertionsEnabled && !predicate())
    throw new AssertionError

The definition is fine, but using it is a little bit awkward:

myAssert(() => 5 > 3)
myAssert(5 > 3) // Won't work, because missing () =>

By-name parameters exist precisely so that you can do this. To make a by-name parameter, you give the parameter a type starting with => instead of () =>.

For example, you could change myAssert’s predicate parameter into a by-name parameter by changing its type, “() => Boolean”, into “=> Boolean”.

def byNameAssert(predicate: => Boolean) =
  if (assertionsEnabled && !predicate)
    throw new AssertionError

Using a by-name parameter

Now you can leave out the empty parameter in the property you want to assert.

byNameAssert(5 > 3)

A by-name type, in which the empty parameter list, (), is left out, is only allowed for parameters. There is no such thing as a by-name variable or a by-name field.

Now, you may be wondering why you couldn’t simply write myAssert using a plain old Boolean for the type of its parameter, like this:

def boolAssert(predicate: Boolean) =
  if (assertionsEnabled && !predicate)
    throw new AssertionError
  • Nevertheless, one difference exists between these two approaches that is important to note. Because the type of boolAssert’s parameter is Boolean, the expression inside the parentheses in boolAssert(5 > 3) is evaluated before the call to boolAssert.
  • By contrast, because the type of byNameAssert’s predicate parameter is => Boolean, the expression inside the parentheses in byNameAssert(5 > 3) is not evaluated before the call to byNameAssert.
  • Instead a function value will be created whose apply method will evaluate 5 > 3, and this function value will be passed to byNameAssert.

The difference between the two approaches, therefore, is that if assertions are disabled, you’ll see any side effects that the expression inside the parentheses may have in boolAssert, but not in byNameAssert. For example, if assertions are disabled, attempting to assert on “x / 0 == 0” will yield an exception in boolAssert’s case.


This chapter has shown you how to build on Scala’s rich function support to build control abstractions. You can use functions within your code to factor out common control patterns, and you can take advantage of higher-order functions in the Scala library to reuse control patterns that are common across all programmers’ code. We also discussed how to use currying and by-name parameters so that your own higher-order functions can be used with a concise syntax.

In the previous chapter and this one, you have seen quite a lot of information about functions. The next few chapters will go back to discussing more object-oriented features of the language.