If there were one thing to highlight as a key factor of Groovy’s adoption, it would definitely be syntax. Groovy offerts over other JVM languages like Scala or Clojure, major advantages :
-
a syntax 95%-compatible with Java : it greatly reduces the learning curve since any Java developer will be able to code in Groovy without having to know nor understand the subtleties of this language. In a reduced team where there’s not much time allowed for learning, it is very important.
-
precious add-ons : utility methods/classes which simplifies the usage of standard JDK Apis and makes code more compact
-
usage of closures, which allows us to focus on algorithmics more than syntax
-
a dynamic type system, which allows newbies to avoid thinking about types
Let’s come back on the last point : I have already said that I planned to use Groovy in edge cases where users'' were not
computer aware''. While this term is quite unfair, it does hide what I consider now as a great success in the introduction of Groovy. The challenge was dared, but it worked : at Lingway, we have three profile types in our technical team : first, developers - like me -, coming from software engineering. Second, consultants, who are trained for programming, but have lower pure technical skills : their main abilities are transforming customer needs into parametrization. Those are the people who write our workflows. Last but not least, linguists, who for most only know about computers as tools : they don’t know anything about programming languages and software engineering. However, thanks to Groovy, all those three profiles are able to collaborate on a single platform, a single language. The ability for Groovy to simplify at most syntax and the ability to create DSLs is amazing.
Let’s take a real example, in the context of acquisition workflows A java programmer would have written (correctly) the following :
Map inputMap = new HashMap()
inputMap.put(com.lingway.lkm.db.corpus.bean.fields.DublinExtendedKind.Title, "Hello, World !");
inputMap.put(com.lingway.lkm.db.corpus.bean.fields.DublinExtendedKind.Body,"Groovy is cool !");
inputMap.put(com.lingway.lkm.db.corpus.bean.fields.DublinExtendedKind.Language,com.lingway.lkm.db.corpus.bean.languages.LanguageKind.ENGLISH);
Usage of Groovy in workflows allows us to simplify it to :
inputMap = [
title: "Hello, World !"
body: "Groovy is cool !"
language: "en"
]
This way of doing allows the workflow ``code'' to be much more readable. It allows us to focus on what to do, not on how to do. This is extremely important and allows us to save time : it is easier to read and maintain. Moreover, it is not required to be an expert to understand what it does : no need to know what a HashMap is. No need to even know that you actually need to instanciate one. Let’s see another example where we would like to sum up the numbers contained in a flat file (one number per line). Our Java developper would have written the following :
File file = new File("/tmp/data.txt");
int total = 0;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8"));
String line;
while ((line=reader.readLine())!=null) {
if (line.length()>0) total += Integer.valueOf(line);
}
reader.close();
} catch (IOException e) {
// this must never happen, and if it does, I don't know what to do
}
System.out.println("total = " + total);
In Groovy, you’d just write this :
def total = 0
new File("/tmp/data.txt").eachLine("utf-8") { line ->
if (line) total += line as int
}
println "Total : $total"
From 13 lines, we fall to 4. Those 4 lines only focus on what to do. At worse, you’ll have to explain to your interlocutor what eachLine or as int does, and you’re done. Likely, Groovy is the perfect candidate for simplifying the usage of Java APIs. One of my favorite example is taken from the Gaelyk documentation, a simplified web framework based on Groovy :
mail.send sender: "app-admin-email-AT-gmail-DOT-com",
to: "recipient-AT-somecompany-DOT-com",
subject: "Hello",
textBody: "Hello, how are you doing? -- MrG",
attachment: [data: "Chapter 1, Chapter 2".bytes, fileName: "outline.txt"]
Here’s an example of a ``mini-DSL'', dedicated to sending e-mails. How could one imagine something simpler ? When you actually know about the verbosity of the Javamail API, it’s no match…
So, thanks to Groovy’s adaptability, we were able to :
-
make our workflows readable
-
write a DSL dedicated to linguistic extraction rules. This language is the core of our internal data extraction tool, and is mainly used by our linguists
About that, the strengths of Groovy in such a tool are multiple :
-
it allows non developers to write rules which are compiled to bytecode then executed by the JVM
-
when the DSL is not sufficient, linguists may ask the developers for help. The latter would then write chunks of Groovy code which perform complex operations
Therefore, what is possible is not limited to what the DSL allows. It is something particularly important to understand : if we had chosen to write a classical DSL, a rule based engine which would use its own syntax, then we would probably have achieved a higher level of readability, but we would also have had to :
With Groovy, you just skip those steps, and you just earn an extra : it’s just code. Even if linguists actually write rules, there’s nothing that prevents us from writing regular code inside. The whole language is usable…
A funny thing is that as time passes by, linguists show an increasing curiosity towards the ``code'' part of rules. They naturally aim at factorizing rules : the language becomes structuring and leads to better code quality !