acefael

.. on gis software

Groovy Goodness

| Comments

I’ve been using Groovy much recently and I wish more people could benefit from the good points. Hence this post.

Now, it usually takes a while to get the sweet side of a new programming language and why to actually use it. But we all understand business. And the main factors why Groovy is good for your business are (1) it runs on the JVM and you can continue to get value out of your existing Java assets and (2) Groovy is a dynamic programming lanuage that allows you to get stuff done quicker.

Java Like

Groovy code can look a lot like Java. There are IDE Plugins. You can write new classes and extend and implement Java classes and interfaces. Joint Compilation allows to have the best of the Java and Groovy worlds in a project. It can be embedded easily into existing apps and build systems, search for “Embedding Groovy” to get clues. There are commercial packages out there with built in Groovy, and the dynamicity you get with this tool is one of the selling points, apart from keeping maintenance costs down.

But also Fun

Groovy is multi-paradigm, which means you can program not only object oriented but also functional style, and more. I like functions and would like to show off how to generate a random tree, to later consume that Groovy-style in a ForkJoinPool. Él código:

1
2
3
4
5
6
7
8
9
10
11
12
def root = {->
  def c = 0, g
  g = { level , dad ->
    if( level < 3 ) {
      4.times {
        dad.get( 'children' , [] ).add( g.call( level+1 , [val:c++] ) )
      }
    }
    dad
  }
  g.call( 0 , [:] )
}.call()

Lets superquick run down what this is about: {->} is a closure without parameters; the last value, dad, is the return value - return keyword not needed. {->}.call() invokes the closure and makes root contain the result of invoking the closure. Inside there’s c, the counter, and g another closure of two parameters that calls itself recursively. The value of calling the g closure is the second argument, but with added children. [:] is a map literal, and j.u.Map.get(key,defaultValue) is an addition to j.u.Map - Groovy adds methods to Java Classes and Interfaces through metaprogramming, and you can do too. Line 6 is all the magic: from dad you get the value under children, or you put a list there and return that ([] is a list literal), and onto that you add a new map with val: c++, but not before adding children to that new child.

The result is a Tree composed of maps with val being our data and children the children of the current node.

Java programmers would not feel at home among the lines above, but the concurrency features in j.u.concurrent are supercool. Just why do I have to inherit from ForkJoinTask I ask. Did they not tell us to prefer Composition over Inheritance and that extends, or inheritance is evil.

Thanks to the great integration of Groovy it is possible to use existing stuff in exciting new ways:

1
2
3
4
5
6
7
8
9
10
11
12
def pool = new ForkJoinPool( 8 )
def task
task = { node ->
  Thread.sleep( aLittleWhile )
  println( node.val )
  node.children?.each { child ->
    pool.execute( task.curry(child) )
  }
}
pool.execute(task.curry(root))
while( false == pool.awaitQuiescence(5,TimeUnit.SECONDS) ) { ; }
pool.shutdown()

This “computes” our tree in parallel with a ForkJoinPool. The task closure is the workhorse. Closures in Groovy implement Runnable and closure.curry(arg) returns a new closure, which is again a Runnable, but where the arg is already “passed in”. node is one of the Maps created above and you see how map values can be accessed with dot syntax. node.children?.each shows off the safe navigation operator - leaf nodes have no children and so simply nothing happens in that line.

After starting the computation in line 10 we only have to wait until it’s worked it’s way through the tree.

More

There’s a lot to the groovy programming language that can make your day more fruitful, and trying to list them all would be futile. Recently I had contact with metaprogramming, Groovy’s Sql Abstraction and of course Embedding. To test out scripts the groovy shell is really cool.

Comments