I have used Groovy now for 6 months. It is the core language implementing uSDLC. It is an excellent language, but it works better as a scripting language than as a full class based system to replace Java.
Performance is a concern. It is fine for uSDLC, but being 10 times slower than Java is a problem. It is not hard to fix by traditional means – analyse bottle-necks and refactor them into Java code. In practice, code bottlenecks are often not that easy to untangle out of the code system.
A related problem is around debugging. Only one in 10 lines in a stack trace point to groovy code – and then many of them do not have a line number.
But my main problem has been with dynamic typing. All my long problem resolution sessions has come down to a mismatch between application and implementation of references. Some were from behind the keyboard (my bad in other words), the Groovy compiler obscured many more. One of the first sort cost me half a day at work recently. A script processed database records from a log based on how old the record was. The original code had:
def age = 0.5 // days
An associate likes taking Groovy code and making it look as much like Java as possible. The refactor became
static final int age = 0.5 // days
The SQL effectively asked for all records that happened exactly now. This problem would not have happened in a purely static or purely dynamic language. Time flies, whether it is finger trouble, as here, or due to Groovy obscuring functionality. This simple search took 2 hours. I have had others due to Groovy that have cost me 2 days.
In theory Groovy++ is the bees’ knees – Groovy with optional static duck typing. Groovy syntax (mostly), Java speed and more readable stack trace. It is in early pre-release, so I was often getting a BUG compiler stack dump with little information on where the code failed to compile. It didn’t take long to learn the language constructs that caused problems. In fully static mode you lose some of the Groovy magic – specifically referring to data of an unknown type.
Map map = … If (map.a) …
This will fail because map does not have a member called a. Fortunately Groovy is flexible and I can use map[“a”] instead. I found that when I converted my code that there were enough similar problems to negate many of the benefits of Groovy. Groovy++ also has a mixed mode where it optimises what it can and passes the rest to standard Groovy. This works well as long as you hand-optimise by writing static and dynamic where needed without hints from the IDE. In the end I was just not confident in the results. If the core Groovy project included Groovy++…
In the mean-time I am learning functional programming. I want to integrate the ways, not become a purist functional programmer. I started working with Closure until I learnt that Scala joined my interests. It is the only language on the JVM that is as fast as Java, it is static typed with ducks and it supports functional programming. I’ll let you know how it stacks up against groovy for me.