The Groovy programming language was started by James Strachan in 2003 and started to gain its popularity quite quickly. Today it is one of the most popular programming languages on the JVM and has fairly large ecosystem including various frameworks for web development as well as other interesting libraries and tools.
We interviewed a few Groovy folks from SpringSource, who in 2008 acquired the company putting out Groovy and Grails, including Guillaume Laforge, the Groovy project lead, Jochen Theodorou and Cédric Champeau–both committers to Groovy, and Andres Almiray, Griffon project lead.
We asked them 12 questions about Groovy, Java and programming in general and here is there (massive) responses in a single, 8-mile long blog post ;)
Extended interview with Guillaume Laforge, Jochen Theodorou, Cedric Champeau and Andres Almiray
1. How do you describe Groovy programming language? Make an elevator pitch! :)
Cedric: Groovy is a multiparadigm language for the JVM. Using a syntax close to Java, it’s an easy to learn language allowing you to write code from scripts to full applications, including powerful DSLs. Groovy is probably the only language on the JVM that makes all runtime metaprogramming, compile-time metaprogramming, dynamic typing and static typing easy to handle.
Guillaume: Groovy’s goal has always been to bring productivity to Java, removing as much boilerplate as possible, while offering great perspectives of dynamicity, and now covering even grounds we didn’t initially envisioned (like our static type checking and compilation capabilities). Groovy is a productive and expressive language for Java developers.
2. If you had an opportunity to design Groovy from scratch again, what would you do differently?
Jochen: Many things in Groovy are like they are because one design goal of the language is to have a high level of integration with Java. If you keep that goal, then there is not really much I would do different that I cannot do in future Groovy versions. If I would not care about Java integration at all, then I would do a lot of things very different. But then there would probably be no users for the language ;)
Cedric: It’s a difficult question. Feature wise, I’m not sure, but implementation wise, you would do a lot of things differently. Immutable data structures, for example, in Groovy core, a clear separation between the AST (class nodes for example) and their reified counterparts (Class), serializable ASTs, … Of course, if we had had invokedynamic since day 1, it’s no doubt for me that the language would have looked a bit different (not that much), but much more easier for us to implement and imagine incredible optimizations.
Guillaume: Some languages take some more opinionated approaches here.
For example, method overloading essentially aren’t allowed in Ceylon. And it simplifies a lot of things. As Jochen mentions, having to deal with Java interoperability (and Groovy is currently the alternative language offering the best and seamless integration), we could have not had to deal with the primitive vs object numbers at all.
Non-reified generics also have their pros and cons, and we might have done things differently. But considering the goal of close relationships between the two languages, Java and Groovy, it’s difficult to do things differently.
Of course, there are various other little details that might have been done better or differently, but I think for the overall approach, I think it’s still valid today and we wouldn’t have changed much from that had we had the opportunity to redesign the language from scratch today.
3. Some JVM languages have different approach to the “billion dollar mistake” (ie null values). What is the rationale for Groovy to approach this?
Jochen: If Hoare had decided different in the 1960s I would probably think different of this, but we are all kids of our time. For Groovy null is just another object with methods and properties. You can even add them using runtime metaprogramming. Sure, we have the null-safe navigation, but other than that, we are more to keen on embracing null, then trying to banish it like a maybe demon in Haskell. Adding it to the type system is currently no option for me, not even for the static compiler.
Cedric: Historically, being very close to Java, Groovy takes the same path, but we have the null safe operator (?.) which helps removing a lot of boilerplate code. Some libraries leverage the Maybe monad to solve the null vs no result difference, but in practice, I find the code much harder to read so I think we have a good tradeoff here. Eventually, with the new static type checking features of Groovy, it wouldn’t be very hard to implement a type checking extension that deals with annotations like
Guillaume: Agreed with Jochen here, since null is there in the host language and platform, better adapt to it and cope with it than completely banish it. Let’s not punish our users because someone introduced null in Java and the JVM :-)
But we’ve been trying, pragmatically, to help users dealing with null, with the safe navigation operator (?.), with the added methods on null (ie. NullObject concept), also with the Elvis operator (?:), etc.
Perhaps, one day we’ll add some more ideas around null, we’ll see :-)
Andres: Groovy is a language that looks at Java directly at the eye and says: I understand your pain. There are a few features in Groovy that makes it easier to deal with nulls. For example, the safe reference navigation operator, also known as ‘?.’. This little guy short-circuits the evaluation of an expression when a null is encountered, for example the expression
foo?.getBar()?.getBaz() results in
null if any of
foo.getBar().getBaz() turn out to be null. The Groovy Truth is another nice addition to the language. Basically what happens is that conditions may be evaluated in a non-boolean context; in this way, null references make the condition fail.
4. It seems that most of the recent JVM languages take advantage of static types. Have statically typed languages won the race?
Andres: I don’t think so. Languages following either static or dynamic typing (sometimes even both!) continue to appear. In my case I’m quite happy with Groovy’s optional typing, which means you’re free to choose if you declare a type or not. Personally I prefer defining types on method signatures when using Groovy.
Jochen: Think of languages appearing like in waves. We had a wave of dynamic languages, now we have a wave of static languages. What follows will be another wave of dynamic languages and so on. There is no winner.
Cedric: Absolutely not. I think static languages also borrow from dynamic languages (otherwise invokedynamic wouldn’t have been necessary) and the opposite is true too. What I lilke about Groovy is that you have the choice, without needing to change of language. Some parts of your code may need more type safety or more performance and you *can* choose to be static here, but in general, it’s not necessary and you can benefit from multiple dispatch and duck typing.
Guillaume: I don’t think statically typed languages have won the race. It’s interesting to see how some dynamic languages like Groovy add some static abilities (static type checking and static compilation), and how some static languages add dynamic traits.
Clearly, there’s a need for both, depending on the requirements or the goal you’re trying to achieve.
It’s not a black’n white situation, as there are benefits to both approaches.
5. In your opinion, how important is the toolset for the programming language (in respect to Groovy)?
Jochen: Java set a new standard when it comes to IDEs. I remember me programming in nothing but a text editor with only syntax highlighting even in the late 90s and still producing thousands of lines of code. For many this is no option anymore, thus it is important to have good tools like IDEs, but also like debuggers and others. It is a main point for adoption.
Cedric: I think the success of the Java language itself has a lot to do with tooling. People are used to IDEs now and I am convinced that once you have a “smart” IDE at hand, your productivity greatly improves, so I’m very happy that Jetbrains and Eclipse both provide amazing support for Groovy.
Guillaume: Some users are happy with vim or emacs, you know :-) But generally speaking, I think good toolset is really critical to the success of a programming language, and to making developers more productive with that language.
JetBrains paved the way for awesome tooling for Groovy back in the day, and our Eclipse friends brought the same experience for Eclipse users, and there’s also the NetBeans team who’s catching up these days. We’re quite gifted to have such great support from the major IDEs!
And beyond that, we should also mention build automation like Gradle, test tools like Spock, or static code analysis with CodeNarc… All these add to the ease of use of the language in a way or another!
Andres: I’m quite happy with syntax highlighting and code formatting, any other fancy features, such as refactoring and debugging, are not that important to me. I’m sure other people will differ with my views. In any case, all major IDEs provide excellent support for Groovy, probably IntelliJ IDEA is the one winning the race, with Eclipse and NetBeans following closely behind.
6. Static typing was added to Groovy 2.0. Why static typing and how does static typing improves Groovy?
Jochen: Static typing was included for two reasons. One is to increase adoption for people who find dynamic typed languages interesting, but are too afraid to make the final step. Those can now sue Groovy statically and step by step try out the dynamic stuff – or not. The other reason is performance related.
The dynamic Groovy 3 will be very near what static Groovy will be, thanks to invokedynamic. But those, that cannot use JDK7 and higher, will not benefit from this. If you then found a hotspot in your code, that could be made faster by being more like Java (because that is what the JVM is optimized for), then people had to switch to Java to solve this. And people complained about it, so we decided, after a long thinking phase, to provide this static typing as alternative.
Cedric: Static typing makes the transition path from Java to Groovy even smoother. A lot of people came (and still come) to Groovy because of it’s lighter syntax and all the removed boilerplate, but, for example, don’t want (or need) to use dynamic features. For them it’s often difficult to understand that Groovy doesn’t throw errors at compile time where they used to have them, because they don’t really understand that Groovy is a dynamic language. For them, we have
@TypeChecked now. The second reason is performance, because Groovy still supports older JDKs (1.5, currently) and that invokedynamic support is not available to them, so for performance critical sections of code, you can have statically compiled code. Also note that static compilation is interesting for framework developers that want to be immune from monkey patching (the fact of being able to change the behaviour of a method at runtime).
Guillaume: It took us years before making that step, after tons of past discussions. There’s a need for it, even for a dynamic language like Groovy, for easing the transition and integration from/with Java, for more safety and performance for critical sections of your code, for being immune to “monkey patching”, etc.
7. How important is Java interoperability for Groovy (or any other JVM languages in general)?
Andres: Other JVM languages prefer to stay away from Java for their own reasons, not Groovy though. Java interoperability is a very important aspect of Groovy, it goes to a point where the Groovy syntax is almost a superset of the Java syntax, thus enabling developers to reuse most of their existing Java code and compile it with the Groovy compiler.
Jochen: I tend to make a difference between interoperability and integration. Interoperability means for me only to be able to communicate with the others. Integrations is for me to appear as much as a native as possible. That goes beyond mere interoperability.
And for Groovy that is high priority item. Many other languages think in terms of a switch from Java land to XY land. Meaning once you have entered constructs from your language you stay there for a while and don’t return to Java landscape soon. This is kind of a context switch and it means a certain cost, that is higher the more you isolate those lands from each other. In this way of thinking, for example, some language generate classes on demand, to let Java interact with the generated class, which is a portal to the real object in the other land.
Stunts like that allow you to do many many things in your land, but crossing the border becomes extremely expensive. In Groovy we cross the borders all the time. If something is executed from Groovy or from Java doesn’t matter so much. It is for this seamless integration that we have static classes and method overloading for example. Sure, they are integral part of Groovy, and not just an add-on, but that is because seamless integration is so important for us. So I think most language actually make the “mistake” to stick to interoperability instead of integration. It is a mistake, because it reduces what you can use from the Java world and that world has many libraries to offer. And as Scala shows, static typed languages are not better.
The reason though is clear, the JVM is too limited to allow for what they seek. And that is why it is arguable if it really can be seen as mistake.
Cedric: I think it’s critical for Groovy, since the language was initially designed as a companion for Java. For example, unlike other languages, we didn’t not rewrite collections APIs, we rely on those available in the JDK and rather add syntactic sugar to make them easier to use. Groovy is a very good language to design boilerplate-less APIs :)
Guillaume: There’s indeed a big step between mere interoperability and full integration. Groovy made the choice for the latter. It means we made some decisions to stay as close as Java as possible, so ruling out some more opinionated approaches, but on the other hand, the benefits are clear in that we’ve got the best seamless experience when mixing both Java and Groovy together, using each language for what it’s best at.
With this approach, we’re not reinventing the wheel, believing we can be smarter than all the other kids, and instead we adapt to the (JVM+Java) environment all developers are used to, and avoid the costs associated with non-standard approaches.
8. What is your favourite application / framework / library written in Groovy and why are you passionate about it?
Jochen: I could of course name Grails, Griffon, Gradle, Gpars, but my favorite is a little game remake I am currently writing ;)
Cedric: Spock is my personal favorite. I find it amazing and it leverages a lot of the features I love in Groovy, like AST transformations. Of course, I could name other frameworks like Gradle, but definitely, Spock wins the race for me :)
Guillaume: The Groovy ecosystem is pretty active and fruitful, so it’s very difficult to choose from.
But like Cédric, I think the creativity palm goes to Spock, especially in how to pushed the envelop so far in bending the Groovy grammar to make tests so readable. I’m really impressed by Spock.
Andres: Well that’s easy, my passion is Griffon, a desktop application development platform for the JVM. Groovy is used as the primary language in the framework, however other JVM languages may be used. For web development I cannot see myself writing web applications without Grails, it’s simply that good not to mention refreshing and fun. Gradle is another precious addition to my toolbox; I use it whenever I have the chance. Finally Spock shows the power of the Groovy compiler and AST expression handling by enabling a simple yet very powerful testing DSL.
And now some questions about Java and the new features that are coming in Java 8, which we covered in one of our previous posts.
9. Are you excited about the features (lambdas, defender methods) in Java 8?
Jochen: Not excited, no. These are things Groovy has been able to do for years. Defender methods look to me like a step only half done, plus I don’t like the mixup with interfaces. Lambdas are much more interesting to me, but once again I see Groovy Closures as the more powerful concept.
Lambdas can surely make Java a better language, but they will complicate Java concept wise as well. Without Scala and Groovy I am pretty sure those features would have never come into existence. They are imho a reaction to pressure from alternatives. And then they had to make a complicated balancing act between staying a beginners language and being sexy to advanced users. And they got stuck somewhere in the middle, resulting in lambdas and defender methods.
Cedric: Lambdas are very nice and they would have been even nicer if they had come to Java sooner :) As for defender methods, I like them too because they are very close (if not equal) to the definition of traits, which are elegant to solve the multiple inheritance problem. One of my favorite additions in Java 8, though, is the ability to have static methods defined in interfaces. Last but not least, Java 8 will also let us annotate almost anything and this is a big bonus.
In Groovy, we’re still bound to what the JVM offers, and sometimes we want to implement features that are not possible due to the fact we’re running on the JVM. In some cases, we can find smart workarounds, but in general, such workarounds just cost too much to be implemented.
Guillaume: I’m not as negative as Jochen here, although his views aren’t that far from the reality in how other languages influenced Java to evolve towards that direction.
Even if Java 8 lambdas, the “stream”-ing reworked collections, or the defender methods aren’t exactly how we would have liked them to be, I think all those things combined should bring some renewal to how developers evolve their APIs, and it should hopefully make for nicer designs and more streamlined usage of new and old frameworks. So overall, I think it’s a good thing for Java.
Andres: Actually, I am! Lambdas open up a world of possibilities for library authors. However their addition to the language wouldn’t be groundbreaking without defender methods: the only way to retrofit existing interfaces with lambda support without breaking binary compatibility. In other words, defender methods make it possible to extends the JSL (for example the Collection utilities) with lambdas without introducing a new Collections library per se.
10. What are the features you would like to see in Java.next?
Jochen: Syntax-wise Java could have stayed in the pre generics age for me. I used it like an JVM assembly language. When I think of Java.next, then not of Java as language, but the JVM. So features I would like the JVM to have are:
- the removal of JVM level primitives
- tail calls
Cedric: I can tell of features I wouldn’t like to see, like reified generics. I think this is a bad idea, although it’s popular. Reified generics will break a lot of code that works just because we *do* have erasure. Although it would be a performance issue since everything would need additional checks at runtime. One more thing is that it would make interoperability between JVM languages much more difficult. For all those reasons, I think it’s not worth adding them.
Guillaume: I agree for the removal of primitives, that would be really nice. I care less for tail calls or continuations, even if those things would be a nice bonus.
But I’d add that I wish the language was a bit more opinionated about the “defaults”: for example, I like how by default things are public in Groovy, or how no-modifier fields are actually properties (with getter/setter). Or I’d like to have type inferencing for variables. If we’d combine those things together, Java.next would likely look already more like Groovy, of course, but above all, that would make the language more enjoyable to write, and easier to read.
Andres: Collection literals would be a great boon, a nice compliment to lambdas. It’s very likely will see them in JDK9 however the roadmap has yet to be set on stone. However in my mind there’s one particular feature that rises to the top: AST manipulation. Groovy has this feature (we call it AST transformations) and I must confess is the best thing since Groovy was released (which happens to be the best thing since sliced bread, no really, it is ;-).
11. Do you think Java 8 will affect adoption of Groovy in any way?
Jochen: I think it is a greater threat to Scala than to Groovy. We focus on dynamic typing based features. People preferring static typing, that prefer Java over Scala, because of Java being more easy, will have problems with Java 8 though.
Cedric: I don’t think so, but it’s true that people not tempted by powerful metaprogramming capabilities, those for whom the only missing thing in Java are lambdas will probably not think of Groovy anymore. But it’s IMHO more a harm to Scala than it is to Groovy.
Guillaume: On my side, I’m not worried about Java 8 and its potential impact on Groovy’s adoption.
Groovy has sweet spots beyond what Java will ever offer, for example in its ability to easily be embedded and compiled on the fly in host applications to provide customizable business rules, and in how it’s capable of offering a very elegant, concise and readable syntax for authoring Domain-Specific Languages.
Java will never ever be able to compete in those areas, and Groovy will always be the best for those kind of use cases.
Andres: My magic crystal ball says: “not much”. Once Java gains lambdas, defender methods and collection literals you’re still missing some other great features that I doubt will ever find their way into the JDK and JSL (certainly not in the next 5 years): AST transformations, operator overloading, new operators such as elvis, spaceship and my personal favorite “?.”. Dynamic method dispatch and method missing (also known as “does not understand” in Smalltalk) can be somehow implemented using JDK7’s invokedDynamic and method handles, though I don’t know how close to the metal such a library implementation may look… oh yes, it’s Groovy :-)
12. How do you see the JVM languages landscape in 5 years?
Jochen: I know I have many many plans for Groovy. But it is difficult to say something about the general landscape. Having so many static language appearing right now, I see them more or less targeting the same people. This means for me, that not all of those will survive the next 5 years. But I am sure other languages will come into public existence by then. I think in 5 years we will probably have the static typing high, that is from then on to be slowly replaced by dynamic languages again – or something else follows.
Cedric: Again difficult to say. Lambdas will probably save Java from loosing users against Scala. On the other side, I think the latter is too complex for the average user. Being type safe is nice, but the type system should not make things harder to write or read, so I think the language will remain a niche language. However, what is sure is that introduction of invokedynamic will give birth to new JVM languages. It’s really an amazing feature that was added in Java 7 and once Java 7 JVMs will be mainstream, we will really be able to leverage its powers.
Guillaume: If we’d be able to forecast the future, we’d be rich, no? We’ll be seeing more of what we see today! We’ll still have strong oppositions between static fanatics and dynamic zealots, while more pragmatic people will understand that it’s not good to be Manichean, and that the real power comes from a blend of both approaches, as gray shares are richer than just black and white.
Andres: Each day that passes by Kotlin and Ceylon get closer and closer to reaching the 1.0 status. They have the potential to grab a sizeable piece of the JVM space. Considering both are statically oriented, sporting similar features but very different goals I wouldn’t rule out a third one entering the fray in the next 5 years. I wouldn’t count out another dynamic language making the scene either.
Thanks to Guillaume, Cedric, Jochen and Andres for their responses–feel free to leave your comments below for them to see!