- 12.1 Functions as Values
- 12.2 Anonymous Functions
- 12.3 Parameters That Are Functions
- 12.4 Parameter Inference
- 12.5 Useful Higher-Order Functions
- 12.6 Closures
- 12.7 Interoperability with Lambda Expressions
- 12.8 Currying
- 12.9 Methods for Composing, Currying, and Tupling
- 12.10 Control Abstractions
- 12.11 Nonlocal Returns
- Exercises
12.7 Interoperability with Lambda Expressions
In Scala, you pass a function as a parameter whenever you want to tell another function what action to carry out. In Java, you use a lambda expression:
var button = new JButton("Increment"); // This is Java button.addActionListener(event -> counter++);
In order to pass a lambda expression, the parameter type must be a “functional interface”—that is, any Java interface with a single abstract method.
You can pass a Scala function to a Java functional interface:
val button = JButton("Increment") button.addActionListener(event => counter += 1)
Note that the conversion from a Scala function to a Java functional interface only works for function literals, not for variables holding functions. The following does not work:
val listener = (event: ActionEvent) => println(counter) button.addActionListener(listener) // Cannot convert a nonliteral function to a Java functional interface
The simplest remedy is to declare the variable holding the function as a Java functional interface:
val listener: ActionListener = event => println(counter) button.addActionListener(listener) // OK
Alternatively, you can turn a function variable into a literal expression:
val exit = (event: ActionEvent) => if counter > 9 then System.exit(0) button.addActionListener(exit(_))