One of the major trends in software development is that languages that offer higher-level features are gaining acceptance. Though there is no official cutoff-point between “procedural” and “high-level,” we are referring to language such as Python, JavaScript, Scala, and Clojure that hover at or around the “functional” end of the spectrum.
Java was was consciously designed as a “jack of all trades” language that stayed within the middle feature-wise and cast as wide a net with developers as possible. While not as much of a “Swiss army knife” as C++, its basic identity has been as an OO language with a procedural tint.
However, the highly anticipated Java 8 release, scheduled for early next year, is bringing Java in line with the languages listed above. Though there is not enough space here to discuss all of the new additions to Java 8, we can examine three features are making the language more modern.
Streams
Every introduction to programming languages quickly introduces students to control loop syntax, whether it be “while,” “for,” or “foreach/for in.” While this is the fundamental way that computer architectures handle repetition across a data set, when it really comes down to it we don’t really care about the order of operations nor do we care about the original contents of the data. We mainly care about the end result. Furthermore, to explicitly introduce a loop structure whenever needed may waste the opportunity to leverage multiple cores; as long as the loops are without side effects they can often be processed in parallel.
For this reason, Java 8 introduces the steam, a new collection type. These collections are more efficient as they can use filter, map, and reduce operations in the course of traversal and can also explicitly use parallelism. They stand to speed up execution and also give Java collection processing a flavor similar to Python.
Lambdas
Derived from Lambda Calculus, the lambda as used in modern programming languages takes the form of an anonymous function which can be passed as an argument just like any data type. They are fundamental to Lisp and its dialects such as Clojure, but even C++ has formally adopted them.
Java has, of course, had anonymous inner classes for a while to fulfill this function in certain circumstances. However, the syntax of the Java 8 lambda is much cleaner and it should be replacing the work of most anonymous inner classes from here on out. Some have argued that the syntax seems to be borrowed from Scala, another JVM language.
Accumulators/Adders
In our discussion of streams above, we noted the importance of getting beyond the single-threaded mindset and start thinking about parallelism. Of course, this is actually easier said than done, but Java’s concurrency model has become fairly mature.
Java 8 accounts for the fact that often when an operation is split among threads, it is for the purpose of summing or incrementing a value. This is a common scalability issue, and to address it in a straightforward fashion the language is adding DoubleAccumulator, DoubleAdder, LongAccumulator, LongAdder. These classes function like atomic variables but function with higher throughput at the expense of slightly looser atomicity guarantees.
Conclusion
Languages such as C++ and Java have been designed to handle almost every conceivable problem with the finest levels of granularity and good performance (compared to more fluid languages). However, with parallelism, scalability, and throughput with distributed operations such as MapReduce being among the most important modern software challenges, performance is no longer just about being able to work close to the metal.