There are a lot of new syntactic features being added to the upcoming JDK 8 and some of this cool “new” things like lambda expressions and extension methods could distract us and make us lose the perspective from the fact that the most important new feature in the JDK 8 is actually its support for parallelism.
As a matter of fact, I believe parallelism support is the only trendy new feature in this release of Java, and from all the “new” things being added, this one is the most important to evolve the language in the right direction. The other features, namely, lambda expressions and extension methods, have been added only to ease the writing of parallel APIs.
Lambda expressions exist since the beginnings of computing. The theory behind them, known as lambda calculus, was formulated by Alonso Church between 1930-1950, and his work constitutes the building block on which the functional programming paradigm rests.
Therefore, since early days, all functional languages provided some form of support for them. For instance, Lisp (1958), SML (1973) and Haskell (1990) have had lambda expressions since the beginning. More recently, many mainstream programming languages have incorporated support for lambda expressions, for instance Python (1991), JavaScript (1994), Ruby (1995), and Scala (2003). And some programming languages have added support for them after their inception, like C# (2007) and, at last, Java 8, almost 55 years after Lisp.
So, this fantastic new feature is being added to Java 8 as well, but only with the purpose of making the writing of parallel APIs simpler, and not because everyone else has it. In terms of functionality, there is nothing in Java that we could do using lambda expressions that we could not do without them. However lambda expressions do make the code more succinct and therefore the APIs developed with them are cleaner. Code written with them tends to be more brief due to their simplified syntax and in Java they eliminate the need for boilerplate code in many scenarios. Also closures can be more easily defined through lambda expressions and these are particularly useful when writing parallel APIs because they make extensive use of high-order programming, and this is the field in which lambda expressions really shine.
Now, in order to add support for lambda expressions to a language like Java, many of the existing APIs, particularly the collections APIs, would need to suffer changes. This makes the evolution of the language more complicated, above all if, as it has been customary in Java releases, we intend to keep backwards compatibility.
This problem becomes more evident when it comes to the evolution of interfaces: once an interface has been publicly released it is impossible to add new things to it without breaking its existing clients. We cannot define new methods without making the clients break because the compiler will require that all the new methods of the interface are implemented. So the big question here is, how can we evolve the existing APIs to support lambda expressions without breaking current clients?
Well, the answer to this question has been the addition of extension methods to the language. And yet again, there is no surprise in this, other languages have supported similar features (i.e. mixins in languages like Ruby, Scala , and extension methods in C#). In Java these extension methods have been defined as a new feature to support implementation of behavior in interfaces. This is a great and logical addition to the language, and one that will certainly simplify the evolution of existing APIs, not only those of the JDK, but also those created by everyone else. And in this case too, we have to recognize that the addition of this new feature has been highly motivated, at the end, by the need to support parallelism.
In summary, we have extension methods because we needed them to add API support for lambda expressions, and we need lambda expressions to make the writing of parallel APIs simpler and cleaner. So, clearly, the feature we should really care about here is parallelism, since it appears to be the source of all good bits in this new release of Java.
The actual trend here is that chip manufactures have hit against the wall of Moore’s law, and have decided, at least for the moment, that the way to increase computational power is by means of multicore architectures, that is by adding more processors to a computer instead of adding faster clocks. This represents an important paradigm shift in the way we write software. The free ride is over, now the new microchips will not make our existing software faster and it is us, the software developers, who are responsible to make the best use of these multicores by means of harnessing the power of parallelism, that is, by dividing the tasks our software carries out in such a way that we can keep all these cores as busy as possible, and without interrupting each other.
Evidently, writing programs and APIs for this new model of computation requires new tools. In Java, this has started with the addition of the fork/join framework in Java 7 and now continues with the addition of parallel streams and lambda expressions in the upcoming release of Java 8.
So, let’s not permit that this cool “new” syntactic features in Java distract our attention of what really matters: the new features for parallelism.
Further Reading:
Nice line of thinking. I should start following your blog, you have a couple of interesting posts!
Of course, the parallelism feature won’t be as impactful for most of us as the other features, e.g. for the ones working in containers where we’re not supposed to occupy more than one thread.
From a library designer’s perspective, defender methods are really the killer addition to the Java 8 language and JVM, not only for backwards-compatibility, but also for API consistency. Think about adding dozens of convenience methods to interfaces, relying only on a few remaining abstract (non-default) methods that are left to implement. In a way, this is what is going to be making the Collections API leap into an awesome “next generation”. With or without lambda expressions.
Too bad, “final” default methods aren’t going to be supported in Java 8…
Yes, definitely the possibility of evolving interfaces is a great new feature in this upcoming JDK 8. I know that for the time being they are only supporting public default methods and static methods. It would have been great if they supported a few other modifiers as you say, but give the time constraints, I believe that this is more than enough for the moment. I see the expert group has been struggling to finish on time. Regarding the comment of not taking much of advantage of parallelism in the server-side of containers, I do not think I entirely agree. The problem we have is that for a while we have not being able to increase the clock speeds in processors due to the problems of overheating and power consumption. So, if our application server is running on a multicore architecture, who is responsible for keeping all those core as busy as possible? It is my contentions that it must be us, the developers. And the whole idea behind this new stream parallel APIs, is precisely that we do not have to think much about the multithreading issues under the hood. It is very likely that the application servers themselves will do a lot of work using this new APIs as well, but if we want to take advantage of the multicore architectures in our servers it must be through the use of this new parallelism. Now, I am not an expert on this field, I am just learning. But this is my understanding of the problem and I definitely intend to experiment with it and perhaps write something about it in the future. Anyway, thanks for stopping by and leaving your comments. You have a great blog too and I intend to follow your posts as well because you write about very interesting things.
I understand what you mean. But according to most interpretations of the J2EE specs, you’re not supposed to start new threads within a container. You’re supposed to delegate multithreaded work to the container itself. Of course, eventually, containers will use the new parallel APIs and expose parts of it to managed applications. Also, of course, you can just “not care” about J2EE specs and start new threads just the same
Anyway, how containers distribute user requests to the various managed threads in their system is their job. So I’m quite positive that most work is already well distributed in a container, long before Java 8. But I agree that things improve for Swing applications, or standalone / headless programs.
In fact today I found there is an ongoing discussion on how all these can be used in JEE. This is not evident yet, I guess future releases of the JEE specs will reveal more on the matter:
http://mail.openjdk.java.net/pipermail/lambda-dev/2013-April/009334.html
Interesting discussion. With these open questions. and with the postponing of decisions to later JEE versions, I now feel even more that JEE and parallelism wasn’t the main driving force for Java 8′s most impactful features (lambda, defender methods), which are much more well-defined.