Home

Function objects

Function objects

We have seen how to define functions and methods using the def keyword. Such a method is compiled to some code with the given name.

In Scala, it is also possible to create function objects without giving it a name. A function object is an object that can be used like a function (that is, it has an apply method).

Here is a simple example:

scala> (x: Int) => x + 1
res1: (Int) => Int = <function1>
Here we have created a function object that takes one Int argument and returns the argument plus one. The type of the object is (Int) => Int. A function object can be used like a function:
scala> val f = (x: Int) => x + 1 
f: (Int) => Int = <function1>
scala> f(3)
res1: Int = 4
scala> f(7)
res2: Int = 8
scala> f(9) 
res3: Int = 10

We can make this even more interesting. In the following function object g, the function definition makes use of a variable more:

scala> var more = 5
more: Int = 5
scala> val g = (x: Int) => x + more
g: (Int) => Int = <function1>
scala> g(4)
res1: Int = 9
scala> g(10)
res2: Int = 15

But what happens if we change the value of more? The answer is that the behavior of the function object changes as well:

scala> more = 10
more: Int = 10
scala> g(4)
res3: Int = 14
scala> g(10)
res4: Int = 20
We say that the variable more is a free variable of the function object. The behavior of a function object depends not only on its arguments, but also on its free variables.

Higher-order functions

When working with collections, there are many common functions that can be implemented as a for-loop:

scala> for (e <- C)
     |   println(e)
Otfried
Jungwoo
Youngwoon

Higher-order methods allow us to concentrate on the interesting part of this loop, namely the print statement:

scala> C.foreach((x: String) => println(x))
Otfried
Jungwoo
Youngwoon
The foreach method is called a higher-order method because its argument is itself a function object. In a sense, foreach is a "meta-function" that works on other functions.

Simplified syntax for function objects

The code above can be simplified, because the Scala compiler knows that the argument of foreach has to be a function object. Therefore we are allowed to omit the type of the argument:

 
scala> C.foreach((x) => println(x)) 
Otfried
Jungwoo
Youngwoon
In this case, there is only one argument, and so we are even allowed to remove the parentheses:
scala> C.foreach(x => println(x))  
Otfried
Jungwoo
Youngwoon
As a final simplification, when the function object has only a single argument and this argument is only used once in the result expression, we can omit the x => part completely and replace the parameter by an underscore:
scala> C.foreach(println(_))  
Otfried
Jungwoo
Youngwoon