alt
November 20th, 2011

By Stoyan Rachev

In the last day of Devoxx, one of the most anticipated sessions was Joshua Bloch‘s The Evolution of Java: Past, Present, and Future. As Joshua put it, the intention of his talk was to critique every single language feature which appeared in the language since its first version. In many ways, this talk was a continuation of Joshua’s talk Java: The Good, the Bad, and the Ugly Parts from the first conference day, already covered in one of Ivan’s previous posts. The session went through all features introduced in Java from 1.1 to 7, explained their intention, showed their “good, bad, and ugly” parts, and finally presented a rating on a scale between “Success” (happy Duke) and “Failure” (Duke shooting himself in the leg).

In the beginning of the talk, the speaker revisited one James Gosling talk from 1996 and a subsequent article The Feel of Java which was published few months later. According to Gosling, Java is practical, not theoretical; it does not introduce new ideas but prefers tried-and-tested things; it feels hyped, playful, flexible, deterministic, and non-threatening. All these characteristics were the main reasons for Java’s worldwide success. There were also naysayers – for example, Bjarne Stroustroup predicted back then that Java will inevitably become more complex and develop implementation specifics. So the ratings of the language features were based on Joshua’s judgment of the extent to which each of them managed to preserve the original “feel of Java”. Features rated as success are simple, useful, and widely adopted, while those rated as failure are either too complex, obscure, or have serious design flaws which lead to “puzzlers”.

Java 1.1

  • Nested Classes. Provide better encapsulation and rudimentary closures. The fact that they are non-static by default is often wasteful and can be deadly; mixing inheritance and non-static nesting is evil. So they are not good enough for closures, should have been static by default, and are still not supported by the VM. Conclusion: not a bad feature, but could have been really good. Neutral
  • Serialization. Besides library, this is also a language feature, since it impacts the design of arrays. One major weakness is that it doesn’t get along with instance control, e.g. singletons. It sort of works, but has a lot of flaws: introduces a hidden constructor; has security holes; leaks private fields; performs abysmally; introduced bugs (Hashtable); designing readObject methods is really hard; final fields don’t mix; requires casting; the serialVersionUID is needless clutter. Conclusion: arguably the worst feature ever added. Failure

Java 1.2

  • strictfp modifier. Addresses an idiosyncrasy in Intel’s x87 math coprocessor. Conclusion: minor wart that could have been avoided. Failure

Java 1.4

  • Assertions. Back in 2001, Joshua encouraged developers to “accept assertions into their lives”. There were and still are good reasons for this, but sadly his advice was mostly ignored – maybe he didn’t preach enough, or maybe developers felt uncomfortable with the uncertainty whether assertions should be switched on or off in production. As a result, most programmers get little benefit from this feature. Conclusion: a net win, but barely. Neutral

Java 5

  • Generics. Enforces specification at runtime, achieving “stronger typing with less typing” as Joshua put it back then. However, adding wildcards at the last minute was a disaster, and generics finally turned out so complex that even the best programmers don’t understand the intricacies. Conclusion: generics are essential, but the design was wrong, “we blew our complexity budget with this feature”. Failure
  • Annotations. General purpose metadata facility. Although it wasn’t perfect, it was well integrated and enabled many successful projects. Conclusion: success – modestly useful for many, critical for some. Success
  • Enums. Combines the power of the typesafe enum pattern with the ease of use of regular enums. Conclusion: rip roaring success. Success
  • Enhanced for loop (for-each). Lets you iterate over collections. Conclusion: most successful language change to date. Success
  • Autoboxing / Unboxing. As Joshua put it, “dragons lurk in these waters” due to many design flaws. This feature achieved reduced verbosity, but the distinction between primitives and objects still exists, and more puzzlers were introduced. Conclusion: instead, generics should have been made to work for primitives. Failure
  • Varargs. Variable number of parameters in method declarations, mainly for printf and reflection. It turned out to be very useful, but not very often. Conclusion: a flawed success, made worse by generic shortcomings. Neutral
  • Static Import. Conclusion: very modest success. Neutral

Java 7

  • Strings in Switch. Useful, but may encourage overuse of String. Conclusion: modest success. Success
  • Binary Literals, Underscores in Numeric Literals. You can express the US national debt as “14_516_500_000_000L”. Conclusion: modest success. Success
  • Multi-catch. Conclusion: no known downside, moderately big win. Success
  • More Precise Rethrow. Conclusion: modest win. Success
  • Type Inference for Generic Instance Creation ( operator). Reduces the verbosity of generics. It is complex under the surface, but this complexity is not exposed to developers. Conclusion: big win. Success
  • Try-with-resources. Introduces linguistic support for the “dispose” pattern. Eliminates lots of verbiage, without significantly complicating the language. Conclusion: big win. Success
  • Safe Varargs. Conclusion: modest success. Success

Where are the puzzlers in Java 7? Maybe there aren’t going to be puzzlers – but don’t bet on it.

Future

Regarding Java 8 and beyond, Joshua advised the language designers “not to give Stroustroup the last laugh”. More is not always better, so before adding a feature a genuine need should be demonstrated.

Conclusion

This talk was informative and entertaining, and offered a very interesting perspective to the history of Java. I liked the speaker’s attitude, really objective and honest even when evaluating features for the design of which he has responsible himself. In Java and other JVM-based languages, are today’s hypes tomorrow’s puzzlers? Or have the language designers really learned from their past mistakes?

I believe Bjarne Stroustroup’s prediction has largely already become true. “The feel of Java” was attractive and compelling, so Java became a great success. However, during its further evolution the language designers had to add many additional features to maintain its viability. For some developers even this was not enough, so they switched to new JVM languages such as Groovy and Scala which favor conciseness, consistency, and expressive power over simplicity. “Polyglot programming” instead of “The feel of Java” is today’s norm – let’s see for how long.

November 19th, 2011

By Stoyan Rachev

After the Devoxx introductory Scala session, about which I wrote in a previous post, I went to Martin Odersky’s talk What’s in Store for Scala. “New developments for Scala: Better tools, full reflection, runtime compilation, and dynamic types.” Based on the abstract and the fact that the speaker is the language creator himself, I was prepared for this session to go into deeper details and provide stronger insights.

Here is a link to the slides from this session.

Overview and Features

Scala is used today in a large number of enterprises, and on a large number of cloud platforms. The main adoption vectors are Web, Trading, and Financial sectors. The main value proposition of Scala is being very fast to first products and scalability afterwards. The language is getting increasingly popular – Martin mentioned that last time he did a talk at Devoxx his talk was the only Scala one, but this year there are so many Scala talks that there is a conflict.

The latest release Scala 2.9 introduced many important new features, such as parallel and concurrent computing facilities yet to appear in Java, faster REPL, progress on IDEs, and better docs. The Play Framework 2.0 is an open web application framework inspired by Ruby on Rails. The Scala Eclipse IDE 2.0 is being completely reworked with the major goals being to make it reliable and responsive. The ambition of Martin is to eventually make it better than Java based on Scala’s excellent type system.

The new release Scala 2.10, which is scheduled for release early 2012 is going to introduce a few major new features:

  • New reflection framework, much more powerful than native Java reflection
  • Reification – types are persistent at runtime, but not as radical as in .NET, since that’s very expensive and complex, on programmer demand with “manifests”
  • Type Dynamic – will help in the interfacing with dynamic languages, lets the programmer selectively suppress errors, similar to “dynamic” in .NET, but simpler
  • More IDE improvements, among them a debugger
  • Faster builds
  • SIPs – string interpolation, simpler implicits

Scalability and Parallelism

Scala comes from “scalable”, and its name brings the promise of scalability. This is why the in the remainder of the talk Martin focused on two important aspects of “Scala in the Large”, large in terms of both many cores and large systems.

Regarding scaling to many cores, Martin repeated again what other speakers at this conference said: Moore’s Law is today only achieved by increasing the number of cores. It takes 24 000 running threads to keep a modern GPU fully loaded. The need for easier and safer parallel computing is sometimes called “PPP (popular parallel programming) grand challenge”.

Here, Martin made a differentiation between “Concurrent Programming” and “Parallel Programming”. The first is about executing programs faster on parallel hardware, while the second is about managing concurrent execution threads explicitly. But both are too hard to do using the familiar Java model with threads and locks.

The root of the problem is in the non-determinism caused by concurrent threads accessing shared mutable state, as demonstrated by the following code snippet:

var x = 0
async { x = x + 1 }
async { x = x * 2 }
// can give 1 or 2

According to Martin, the only way to really solve the problem is to get rid of the mutable state. But this means programming functionally, and this is why Functional Programming (FP) has become mainstream and popular only very recently. FP here has the advantage of offering a completely different mode of thinking: if you think imperatively, you think in terms of time, while if you program functionally, you think in terms of space. If you look at space, solving a problem in a parallel way is easy, it’s like building a cathedral with 1000 workers each of them working on its own piece. But if you look at time, it’s much more complicated, so you need to think about protecting your resources from concurrent access. However, we as humans are much better at thinking optimistically rather than pessimistically, that’s why from a thought perspective the functional way is much simpler than sticking to an imperative mindset.

In this space, Scala has many appealing features – it is not only agile, both object-oriented and functional, and both safe and performant, but also offers excellent parallel processing facilities. In Scala’s toolbox for parallelism there are parallel collections and parallel DSLs as core language features, and for concurrency there are actors, STM, and futures, all available in the Akka framework.

Since Akka was already presented in a previous talk, Martin focused on the parallelism features that are provided by the core language. First, he outlined parallel collections. He showed a simple Scala class Person with a name and an age, and then used it to partition an array of people to minors and adults sequentially. He compared the Java and the Scala code, outlining again the much more concise syntax of Scala, closer to the problem domain – a simpler pattern match, an infix method call, and a function value.

val people: Array[Person]
val (minors, adults) = people partition (_.age < 18)

He then came to the parallel case, which in Java would be rather hard to implement, while in Scala you can just add .par on people and the job is done.

val (minors, adults) = people.par partition (_.age < 18)

The above code converts the array into a “parallel array”, and then all operations that make sense to be executed in parallel suddenly are executed in parallel. There is a hidden contract, however – you give the system permission to execute operations in any order it likes. This means there should not be any side effects. But fully avoiding side effects means that you need to be functional, otherwise it would just not work. Martin said that he is very curious what will happen in Java after the announced introduction of similar features in Java 8 – according to the speaker, if Java doesn’t morph into a functional language, it’s way too dangerous to use that.

The parallel collections in Scala use Java 7 Fork/Join framework to split the work by the number of processors and introduces an adaptive mechanism in which the number of slices is changed dynamically depending on the workload, to get an optimal performance out of the box. The bottom line: they are easy to use, concise, safe, fast, and scalable.

But still, how can we reach the mentioned tens and thousands of threads in an application to fully load a modern multi-core processor? Parallel collections and actors are not sufficient. Here Martin makes a “bet for the future” that one possible solution could be parallel embedded DSLs. The idea is to capture the parallelism from the problem domain, which the compiler is not able to extract automatically, by using a Scala-based DSL.

Here Martin showed an example from EPFL / Stanford research. Liszt is a DSL for physics simulation, which is used for example to simulate airflow in hypersonic jets. It is mesh-based, with very irregular meshes. Liszt is implemented by a functional program that constructs a representation of itself with AST (abstract syntax trees) which is then converted to code which is optimized by the size of the problem and the hardware. According to the speaker, the performance of this implementation beats that of hand-written C++ code; problems tend to be so complex that humans can’t do an optimal job anymore.

Reflection

In the remainder of the talk, Martin focused on another new feature in Scala 2.10 – its reflection facilities. The goal here is to achieve the analogue of Java’s reflection, but with Scala’s full types. Programmers should be able to ask an instance for its Scala runtime class, then ask the class for its supertype, obtain its members, etc.

Reflection in Java is limited – for example it doesn’t tell you if type A conforms to type B. Why wasn’t this done in Java? It turns out this would only be possible if the reflection implementation would duplicate essential parts of the compiler, which is too hard and may lead to serious consistency issues.

How to do better? Martin looked at dependency injection and introduced the The Cake Pattern for solving cyclic dependencies in dependency injection. It turns out this approach can be used to achieve better reflection, as Martin put it to “bake a cake that’s both compiler and reflection”. There are three cakes: reflect.internal.Universe, extended by nsc.Global (scalac) and reflect.runtime.Mirror. To avoid exposing too much detail, the API facade scala.reflect.api is introduced on top of reflect.internal.Universe.

In conclusion, Scala is a very regular language when it comes to composition – everything can be nested, everything can be abstract – methods, values, types, and last but not least the type of this can be declared freely. All this allows us to solve previously unsolvable problems, such as achieve better reflection.

Conclusion

Although I was not able to fully grasp some of the more intricate technical details of this talk due to my limited knowledge of Scala, after it I felt even more motivated to further explore this language. Yes, it is more complex than other JVM-based languages (not to mention Java itself), but I think it’s quite possible that this complexity reflects the essential complexity of the problem domain, rather than being accidental. Based also on other Devoxx talks, I believe that the much praised Java simplicity is indeed a myth, since it offers programmers seemingly simple, but often inadequate language facilities in terms of conciseness and expressive power. In this respect, Scala has taken the opposite direction, and has so far positioned itself as the most promising “potential Java killer” (as other speakers called it) in the new JVM languages space.

November 17th, 2011

By Stoyan Rachev

In the afternoon of Devoxx Day 2, the new language parade continued with Andres Almiray’s overview of The Groovy Ecosystem.

Unlike Scala, I have some previous experience with Groovy. I studied the language earlier this year and was really impressed by its richness and expressive power. You could think of it as “Java on steroids” or as “Scala with a Java-compatible syntax”. On the downside, in my experience its dynamic typing, Eclipse support and performance were not that great. At the time, I thought Groovy might still be ideal for internal use, in any case much better than ant, batch files, or other scripting languages we use so far in this area.

The session abstract says that “Groovy is the fastest growing JVM language out there. It might be because it is so easy for Java developers to pick it up, but also because there’s an increasing number of projects and libraries that make use of Groovy as the starting point.”

Instead of presenting language or framework concepts on slides, Andres showed just a single slide per framework, and moved straight into coding to demo their features. Most of the demos went flawlessly and were quite impressive. You could check the slides here.

Grails

Grails is a popular Web application framework similar to Ruby on Rails. It builds on top of Spring and Hibernate and has more than 600 plugins available. In a few minutes, with the help of few console commands and a text editor (no IDE), a new “Book / Author” application was born and then enhanced by adding custom actions, views, and even tags. One could use the built-in Grails console as an interactive playground to test various dynamic methods (added by the framework), or other behavior of the application. Finally, it could be further enhanced by adding more plugins, and even by creating a custom plugin, all with very little effort.

Griffon

Griffon is another framework that brings the power of Grails to desktop applications. It also has a very rich plugin ecosystem, and is “polyglot aware”. Using Griffon is very similar to using Grails, just the grails command is replaced with griffon. Swing or SWT components can be created and wired with a special DSL, instead of custom code. The same Griffon application can be started as a standalone app, as an applet, or with Java Web Start by just using a different command for launching it. Properties of UI controls can be easily bound to other properties or the model with very little code. With a simple annotation one could control if the controller code runs in the same or in a different thread than the UI (event dispatcher) thread.

There are also archetypes that allow you to bootstrap applications in a different way. In the demo, one of the built-in archetypes was used to create an application with a predefined set of models, views, and controllers and a richer set of features. Griffon also has a very lightweight event bus. With it, you can publish an event and then listen to that event following a simple convention, in the same or different threads.

What if you are not allowed Groovy, but forced to use Java? You could still use Griffon by specifying the correct “file type” and “archetype” when creating your application, which creates Java code instead. If a certain plugin is installed, Groovy annotations such as @Bindable could be used as well. The Java version took a few rounds to compile correctly since the speaker didn’t use an IDE. As one might expect, it had twice the amount of lines of code compared to the Groovy application.

With Griffon, you can package your applications as a zip file, or as a different distribution type (dmg, izpack, rpm, …) with the help of the installer-plugin.

Gaelyk

Gaelyk lets you access Google App Engine (GAE) services by lightweight abstractions. According to Andres, it is “the PHP for GAE”. It also has an emergent plugin system.

Gradle and Gant

Gradle is a better way to build. This is a Groovy DSL for building projects, which harnesses the power of Maven conventions. It is actually similar and compatible with Maven, just much less verbose. If the conventions are followed, a simple application can have a build script which contains just a single line of code. In the demo, this simple build finished in 6 seconds the first time and much faster after that, because Gradle is smart enough not to repeat the steps that are not needed. If conventions are not followed, Gradle still gives you the full power to configure what you may need. Unlike Maven, it uses a very clear and concise syntax, typical for Groovy DSLs. Multi-projects in Gradle are also much easier than in Ant or Maven. Just by calling install, Gradle generates pom files and install the artifacts in the local Maven repository.

Gant is a “groovier” version of Ant – take away the XML and substitute it with a real scripting language. Although both Grails and Griffon still use Gant, it’s now somehow fading away because of Gradle.

Easyb and Spock

Easyb enables Behavior-Driven Development (BDD) for Groovy and Java. Some claim that BDD is TDD done right. When doing BDD, you define expectations from your customer’s point of view, write it in a natural language, and finally sprinkle some code inside. With Easyb, you could test both Java and Groovy code. It follows the usual BDD “given / when / then” syntax for defining stories and scenarios.

Spock is a testing DSL similar to RSpec. It hijacks the Groovy syntax to create something really “funky” using features that are available in the JVM, but not really exposed in programming languages. Did you know that you could have method names that are strings? With a simple @Unroll annotation, one could have a single method test multiple inputs, which is “unrolled” into multiple tests. Good bye @RunWith(Parameterized.class).

More …

CodeNarc is Groovy’s version of FindBugs and PMD. It enables static code analysis for Groovy code, and has plugins for Grails, Griffon, and Gradle. Andres showed how to add the plugin to Gradle and analyze the Groovy code with it. You could define what rules you want to apply using either XML or a Groovy-based DSL.

Concurrency is a new hotness. GPars brings concurrency management abstractions and facilities to Groovy, including actors, dataflow, and fork / join.

Ratpack is a clone of Sinatra for Groovy. It’s a nice way to create REST-based API for a command line tool.

GContracts provides “contract-oriented development”, which allows you to define pre-conditions and post-conditions to methods in the form of annotations (@Requires and @Ensures). This should not be seen as an alternative for testing or semantic validation.

Groovy++ is an attempt to make certain extensions to the Groovy language such as static compilations, traits (similar to Scala), immutable data structures, etc.

Conclusion

It seems that not only the Groovy language has all the features you may not see in Java in the next 10 years, but also that those Groovy guys have built up frameworks comparable (and to a large extent compatible) with whatever is in the Java SE / EE space, just much easier to use. And despite that they are built as open source by different people, they are still amazingly consistent. How did they manage to do all of that without JCP?