Why Groovy is so groovy or a beginners guide to hacking Groovy

Gregory Dickson
Jul 21, 2017 · 6 min read

I personally came to Groovy as part of an undercover project to do something quickly while leveraging previous Java experience. I had been contracted to develop a web application and it “had to be in Java”, according to the client, although they had no real hard requirements to speak of. I had been developing in Ruby on Rails for a couple of years so when I had to develop a “Java” web application, I went searching for web frameworks that might be as productive as Ruby on Rails.

I quickly found Grails which used a language that I had not heard of called Groovy. I realized that I could deliver the application in Tomcat with a Java war (web archive) file and the client would never be the wiser. I did have a background in Java and one dynamic language, Ruby, so when I started writing Groovy I would just try something and see if it would work and more often than not it just worked. However, over the months and then years I found many features and libraries in Groovy that really increased my productivity. I also found that with Groovy (and Grails) I could deliver a highly performant application just as quickly as I could in Rails with additional features such as concurrency (using GPars with Groovy) and very high performance, comparable with Java, using static compilation.

In one instance I was in a startup where I built a concurrent search algorithm and we had a competitor, in the same city no less, using Rails to do the same exact searches (we were both travel websites) and our searches returned in about 13 seconds to their 30 seconds. I attribute this to being able to easily, and easily is the keyword here, create a concurrent multi-threaded algorithm.

Looping in Groovy

The first Groovy features that I wish I had learned sooner were .each{}, .eachWithIndex{}, and .times{} in order to get rid of dreaded for loops. There are plenty of articles that go into how Groovy adds methods to an object and dynamic dispatch so I will not go into those details and just take a more pragmatic approach of how to get more productive with specific Groovy features. If you want to play around with some Groovy code, the fastest way to get going is to use the Groovy web console at http://groovyconsole.appspot.com/ (preferred as it has better error output) or the Groovy playground at https://groovy-playground.appspot.com/. I would also recommend installing Groovy and Gradle locally if you really want to get into Groovy.

Edit: I just saw this code playground that supports Groovy, https://www.jdoodle.com/execute-groovy-online and one of the few coding challenge sites to support Groovy is HackerRank.com

Before we get into using .each{}, it is important to understand Groovy Lists and Maps. In Groovy, like Javascript, you can create a map literal and a list literal like so:

In Groovy you can define the type or interface of the Map or List reference and this is becoming more common in idomatic Groovy as you can now optionally statically compile Groovy code which requires that the objects are typed:

Under the covers, Groovy actually uses Java’s ArrayList for the List and LinkedHashMap for the Map and adds many methods to them, as you will find out. These default implementations are good choices in my opinion and work in 99 percent of cases. If you really need the properties of a specific List or Map implementation then you can always jump into Java in your Groovy program as Java compiles as Groovy and you probably are at the level where you have some detailed performance requirements for your Lists and Maps or you have used them in Java for years and want to in Groovy. You can also create an empty Map or List literal and then add items to it later.

Again, [] or [:] is an object literal syntax. If you have used Javascript's object literal syntax then this may seem familiar. However, Groovy does not have the same idea as a generic object literal like Javascripts var someObject = {}; or with ES6 let someObject = {};, only Lists and Maps for now (Edit: Groovy actually has a complete system of defining Closures and incredible ways of using them and they are basically object literals or function literals, I will write my next Groovy post about Groovy Closures). The left shift << operator, in Groovy, is used by a Map and a List to append items, in addition to many other syntaxes for adding items or combining lists and maps including the overloaded plus + operator, .plus(), .add(), .addAll and probably more. I still find new jewels of syntactical sugar in the docs.

Object as Key

A common gotcha with Groovy maps is using an object as a key in a Groovy Map. You may have a string created dynamically and then want to use that string as a key in a Map. In that case you have to surround the reference with parenthesis, (), so that it will reference the string value inside the object and not the actual string used as the object reference.

.each{}

So, on to the eaches. The basic each syntax is very straightforward:

At its most basic, the each syntax provides a block with a scope, which is actually a Groovy Closure but you don’t need to know that to use it, that is looped over for each element in the list, providing a default, untyped, reference to the item with the keyword it. Expanding on that, you can provide a specific name to the reference and type the object reference in the loop.

The arrow operator, -> is simply there to separate the inputs and the logic to be executed in the 'loop'.

.eachWithIndex{}

You also have .eachWithIndex{} that provides an index within the loop. The first parameter is the item in the list and the second is the index.

A couple of things to understand about this type of looping. First, you cannot break out of an .each{} block. Also, you can nest them, but you must name your references to avoid confusion, and errors.

If you absolutely want to break out of an each, then you can throw an exception, however most would say that you should avoid this pattern for both readability and performance reasons. If you do use an exception, you should probably create a custom exception to avoid catching real errors such as FormatExceptions or IOExceptions, etc. and throwing them away, creating a difficult piece of code to debug.

There are some options within the eaches that provide for other types of logical control. You can return from the loop using the return keyword. Remember, it will continue looping until the end of the List or Map.

.eachLine{}

In the same vein as each, Groovy adds an eachLine{} method to Strings that can be used on multiline strings, any string with newline characters. One note, a Groovy multiline string created with a triple single quote will contain a newline character as the first character. It is possible to strip that initial newline character by escaping with a backslash. Note, Groovy has both triple single quoted multiline strings and triple double quoted multiline strings, more on those in future articles.

The .eachline{} method can name both the line reference and the line count, or index in the block.

.times{}

The other quick and neat way to create a loop, again, one that you can’t break out of, is .times{}. I have used this one in many cases. However, due to some implementation details, I find that exceptions thrown inside of a times loop seem to be discarded and re-thrown as a generic exception. I have had to recode times loops as for loops on multiple occasions. One of my favorite uses of times loops is in cases where I need to create a nested loop.

Overall, my approach to development on the Java Virtual Machine is one where I start all my projects in Groovy, occasionally jump into Java, and sometimes mix and match Java classes with Groovy ones. Using Gradle it is relatively trivial to combine Groovy and Java, inherit from either side, and have the best of both worlds. Personally, I tend to avoid inheritance hierarchies but one level of inheritance can be useful. You can blend an object oriented style, when useful, with a functional style, also, when useful. I did spent six months coding Scala, while interesting, it was a breath of fresh air to return to Groovy.

)

Gregory Dickson

Written by

OG Hacker, I prefer being outside. Serial CTO.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade