One of the presentations I most eagerly anticipated for JavaOne 2012 was Brian Goetz's "The Road to Lambda." The taste of Lambda at last night's Technical Keynote only added to the anticipation. Held in the Hilton Plaza A/B, this was a short walk from the previous presentation that I attended in Golden Gate A/B/C. I had expected the relatively large Plaza A/B to be packed (standing-room only), but there were far more empty seats than I had expected.
Goetz started talking about Java 8 being "in the home stretch," but not yet released or ready for delivery. He said he expects Java 8 and Lambda to be available about this time next year. Goetz said that you "can write any program that's worth it to write using Java," but that Java 8 will make it much easier to do so. His slide "Modernizing Java" talked about Java SE 8 "modernizing the Java language" and "modernizing the Java libraries." His last bullet on the slide stated, "Together, perhaps the biggest upgrade ever to the Java programming model." This has been my feeling and that's part of why I was surprised this presentation was not better attended.
Goetz stated that a lambda expression is "an anonymous method." It has everything that a method has (argument list, return type, and body) except for the name. It allows you to "treat code as data." A method reference references an existing method. Goetz reiterated the huge fundamental shift to writing and using libraries that will result from addition of lambda expressions.
Goetz pointed out that most languages did not have closures when Java started in 1995, but that most languages other than Java do have closures today. He then summarized some of the history of closures in Java in the slide titled "Closures for Java - a long and winding road." He referenced Odersky's and Wadler's 1997 "Pizza" (1997), Java 1.1's inner classes (1997), and the 2006-2008 "vigorous community debate about closures" (including BGGA and CICE). Project Lambda was formed in December 2009 and associated JSR 335 was filed in November 2010. It is "fairly close to completion" today.
Goetz stated that the for loop is "over-specified for today's hardware" while describing the "accidental complexity" associated with use of "external iteration" that we frequently use today. I agreed with the point he made that the "foreach loop hides complex interaction between client and library."
The goal of lambda expressions allows the "how" to be moved from the client to the library. Goetz emphasized that this is more than a syntactic change because the library is in control with lambda expressions and it is an internal iteration. Goetz stated, "The client handles the 'what' and the library handles the 'how' and that is a good thing." He added that lambda expressions have a profound effect on how we code and especially on how we develop libraries.
Goetz discussed the new
forEach(Block) method added to collections using the new default implementation mechanism for Java interfaces. Goetz differentiated that Java has always had multiple inheritance of types (can implement multiple interfaces), is now (Java 8) going to have multiple inheritance of behaviors (default method implementation available for interfaces), but still won't have multiple inheritance of state (the last of which he describes as the most dangerous). Goetz had a slide dedicated to explanation of why "diamonds are easy" when you take date (state) out of the multiple inheritance.
Goetz had a nice slide summarizing "Default Methods - Inheritance Rules." This slide featured three rules. He pointed out that "if default cannot be resolved via the rules, subclass must implement it." Goetz pointed out that an interface could provide a "weak" default implementation and subclasses can provide better implementations.
Another advantage of default methods on interfaces is that the default implementation can throw an exception (such as UnsupportedOperationException) for optional methods so that subclasses not implementing the optional behavior don't need to do anything else. Goetz also showed how lambda expressions enable the addition of reverse() and compose() methods to Comparator.
Goetz showed several examples of code that illustrated that lambda expressions allow for "cleaner" and "more natural" representations. In his words, "the code reads like the problem statement" thanks to the composability of the lambda expression-powered operations. There is also "no mutable state in the client."
One of Goetz's slides had a quote I plan to use in the future: "Laziness can be more efficient." The context of this is that laziness can be more efficient if you're not going to use all of the results because you can stop looking once a match is determined. Stream operations are either intermediate (lazy) or terminal (naturally eager).
The Stream is an abstraction introduced to allow for addition of bulk operations and "represents a stream of values." Goetz's bullet cautioned that a Stream is "not a data structure" and "doesn't store the values." The aim here was to avoid noise in setting things up and try to be more "fluent."
Goetz stated that "one of Java's friends has always been libraries." He talked about how lambda expressions enable greater parallelism in the Java libraries. Goetz stated that fork-join is powerful but not necessarily easy to use. Goetz emphasized that "Writing serial code is easy; writing parallel code is a pain in the ass." Lambda expressions will still require parallelism to be explicit, but should be unobtrusive with lambda expressions and their impact on the libraries.
To emphasize Project Lambda's effect on parallelism in the libraries, Goetz showed a painful slide with how parallel sum with collections would be done today with fork-join and then another slide showing the much simpler use of lambda expressions. The point was made: much less code with lambda expressions, making the business logic a much larger percentage of the overall code.
The slide "Lambdas Enable Better APIs" drove home the powerful and welcome effect of lambda expressions on the standard Java APIs. He emphasized that the "key effect on APIs is more composability.
Goetz stated that we typically prefer evolving programming model via libraries than language syntax for numerous reasons such as less cost, less risk, etc. He summarized his presentation by stating that times have changed and it is no longer a radical idea for Java to support closures.
One of the attendees asked why lambda expression method support is on the collections rather than on iterators. Goetz said that although C# did approach it from the iterator approach, his team found it less confusing for developers to have the methods on the collections instead of on the iterators.
In response to another question, Goetz stated that reflection on lambda expressions is not yet available due to its complexity. In response to another question, Goetz stated that lambda expression support is built with invokedynamic and method handles. This is part of an effort to make lambda expressions "fun to program" and "fast."
Another question led to a really interesting response from Goetz in which Goetz explained that the availability of internal iteration within a collection itself means the iteration complexity will be encountered by far fewer people (library developers rather than end user developers). Goetz encouraged attendees to run Java 8 drops currently available to help determine if Lambda expressions are being handled correctly. Goetz remarked, "The most valuable contribution we get from the community are people who say, 'I tried it out and found this bug.'"
Goetz started this presentation by stating that this was one in a long line of presentations at previous JavaOne conferences and other conferences on the state of lambda. What was different about this one, however, is that Project Lambda is "almost there" and, with that in mind, it seems that the syntax and concepts are largely in place. This obvious solidification of the APIs and syntax is welcome and this presentation met my very high expectations for it.