Java Reference
In-Depth Information
Lambdas as Closures
Java 8's lambdas act as closures. Although the term “lambda” and “closure” are effectively interchangeable in
most programming conversations, there is a technical difference. The good news is that Java 8's lambdas are
also closures, so you can call them either and be technically correct. Understanding the distinction, however,
helps you be clear about what you are saying.
The term lambda comes from a branch of mathematics exploring what can and cannot be computed,
specifically from a structure called the lambda calculus . The lambda calculus explores function application
as the primary action in computation, and so it works with functions in the most abstract sense, without
any consideration of what the function itself might represent or calculate. Functions themselves are the
relevant values in the lambda calculus. When programming languages borrow the term lambda from the
lambda calculus, they mean functions that can be treated as values. A lambda can be assigned to a variable
(or multiple variables), passed around as method arguments, and generally manipulated like one might
manipulate the values 2 , true , or "foo" .
The term closure , however, refers to a later innovation of the lambda. For Java developers, it is
easiest to think of the term closure as meaning encapsulating function . In the same way that an object can
encapsulate state and expose it through a particular API (such as properties exposing fields), a closure can
also encapsulate some state and then act on that state wherever and whenever the closure is invoked. The
“close” part of closure refers to “open” versus “closed” variables. This idea comes directly from mathematics:
a variable that does not have a value bound to it is said to be “open,” while a variable that does have a value
bound to it is said to be “closed.” A closure is a lambda that closes certain variables, and it does this by
enclosing a variable environment.
This may sound like a strange and technical concept, but it is actually quite familiar in practice. Before
Java 8 introduced lambdas, Java arguably already had closures in the form of anonymous inner classes. 1
Anonymous inner classes could capture variable state in one context and execute on it in another: see
Listing 2-6 as an example. In that case, the anonymous inner class implementing Greeter closes the variable
greeting . You knew you were creating a closure in Java whenever the compiler would insist that you add
final to your variable or parameter declaration.
Java 8's lambdas also act as closures, meaning that they will capture variables that are in scope. This is
just like how the anonymous inner classes did it, and an equivalent example of a lambda as a closure is given
in Listing 2-7. As a bit of syntactic sugar, though, you no longer have to explicitly declare your variables as
final : the compiler implicitly makes enclosed variables final, and will raise a compiler error if they are not
treated as final. 2
Listing 2-6. Anonymous Inner Classes as a Closure
public interface Greeter {
String createGreeting(String whom);
}
public static void main(String[] args) {
// Create variable in this scope
final String greeting = "Hello, ";
1 This strange fact provides the opportunity for a rather annoying and pedantic yet useful interview question:
“Please write a closure in valid Java 7 syntax.”
2 We will address why the final variables are necessary in the section below named “Lambdas Should Always Be
Threadsafe.”
 
Search WWH ::




Custom Search