How to define a Scala method that accepts a function parameter

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 9.3, “How to define a method that accepts a simple function parameter.”

Problem

You want to create a Scala method that takes a simple function as a method parameter.

Solution

This solution follows a three-step process:

  1. Define your method, including the signature for the function you want to take as a method parameter.
  2. Define one or more functions that match this signature.
  3. Sometime later, pass the function(s) as a parameter to your method.

To demonstrate this, define a method named executeFunction, which takes a function as a parameter. The method will take one parameter named callback, which is a function. That function must have no input parameters and must return nothing:

def executeFunction(callback:() => Unit) {
    callback()
}

Two quick notes:

  • The callback:() syntax defines a function that has no parameters. If the function had parameters, the types would be listed inside the parentheses.
  • The => Unit portion of the code indicates that this method returns nothing. I’ll discuss this syntax more shortly.

Next, define a function that matches this signature. The following function named sayHello takes no input parameters and returns nothing:

val sayHello = () => { println("Hello") }

In the last step of the recipe, pass the sayHello function to the executeFunction method:

executeFunction(sayHello)

The REPL demonstrates how this works:

scala> def executeFunction(callback:() => Unit) { callback() }
executeFunction: (callback: () => Unit)Unit

scala> val sayHello = () => { println("Hello") }
sayHello: () => Unit = <function0>

scala> executeFunction(sayHello)
Hello

Discussion

There isn’t anything special about the callback name used in this example. When I first learned how to pass functions to methods, I preferred the name callback because it made the meaning clear, but it’s just the name of a method parameter. These days, just as I often name an Int parameter i, I name a function parameter f:

def executeFunction(f:() => Unit) {
    f()
}

The part that is special is that the function that’s passed in must match the function signature you define. In this case, you’ve declared that the function that’s passed in must take no arguments and must return nothing:

f:() => Unit

The general syntax for defining a function as a method parameter is:

parameterName: (parameterType(s)) => returnType

In the example, the parameterName is f, the parameterType is empty because you don’t want the function to take any parameters, and the return type is Unit because you don’t want the function to return anything:

executeFunction(f:() => Unit)

To define a function that takes a String and returns an Int, use one of these two signatures:

executeFunction(f:String => Int)
executeFunction(f:(String) => Int)

See the next recipe for more function signature examples.

Scala’s Unit

The Scala Unit shown in these examples is similar to Java’s Void class. It’s used in situations like this to indicate that the function returns nothing (or perhaps nothing of interest).

As a quick look into its effect, first define a method named plusOne, which does what its name implies:

scala> def plusOne(i: Int) = i + 1
plusOne: (i: Int)Int

scala> plusOne(1)
res0: Int = 2

When it’s called, plusOne adds 1 to its input parameter, and returns that result as an Int.

Now, modify plusOne to declare that it returns Unit:

scala> def plusOne(i: Int): Unit = i + 1
plusOne: (i: Int)Unit

scala> plusOne(1)
(returns nothing)

Because you explicitly stated that plusOne returns Unit, there’s no result in the REPL when plusOne(1) is called.

This isn’t a common use of Unit, but it helps to demonstrate its effect.

See Also

Scala’s call-by-name functionality provides a very simple way to pass a block of code into a function or method. See Recipe 19.8, “Building Functionality with Scala Types”, for several call-by-name examples.

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.