Sunday, February 26, 2012

Closure in Groovy

The purpose of this article is to go smoothly with some of the main features offered by Groovy and explained closure which is one of the biggest hurdle to understand Groovy for non functional programmers. I expect that readers of this article have rudimentary understanding of the groovy syntax; If not I would recommend to check the official Groovy website (http://groovy.codehaus.org/). Unlike Java which is a statically typed OO/imperative language, Groovy is a dynamically typed hybrid programming language that supports both Imperative and Functional paradigm.

One of the strongest case for Groovy (for Java programmers) VS Python and Ruby is that Groovy syntax is super set of Java (almost with some quirks), and Groovy integration with Java is seamless. Note: once you become more familiar with the Groovy semantics e.g. dynamic and duck typing, functional paradigms etc, and go skin deep you will realize that Java and Groovy are quite different languages that serve the different needs. Understanding the semantic differences between the two paradigms could be quite overwhelming and the best way to grasp these concepts is get your hand dirty with the coding. Before we deep dive into coding let’s talk about some of the main concepts of Groovy.  Below is the list of features that summarize Groovy for Java developers:

  • Just like Java Groovy compiles as Java byte code
  • Unlike Java, Groovy can be utilized as a scripting language too
  • Groovy enhance Java API with Groovy JDK (http://groovy.codehaus.org/groovy-jdk/), besides this Groovy provides its own API (http://groovy.codehaus.org/gapi/) too that has tons of handy features
  • The most important feature that differentiates Groovy from Java is that besides being Imperative Groovy also supports functional paradigm. What it means is that in Groovy universe “Functions” are first class citizens and they can be treated as a regular data types. Hence Groovy supports the notion of Closure that are the heart of any “Functional” language
  • Groovy has very powerful MOP (Meta Object Protocols) facility

Enough theory so let’s jump into closure with one thing in mind, think of closure as regular functions on steroid:

 def a = {param -> println param} // a closure in groovy  

In the code above we define a variable called “a” and assigned it to a closure. In Groovy closures are defines just like any other function with curly braces. Anything before “->” are the method parameters and anything after “->” are method body. Note: a method body can be an expression as well as statements. The biggest hurdle to understand the closure is how to use this closure. Note: Groovy supports closure natively and closures can be used as a regular data type in Groovy universe. It means you can pass and return closure just like any other data type to and from a method. The code below shows a typical use of the closure defined above:

 5.times (a) //Calling the above closure with built in times function in Groovy  

Output:    0
               1
               2
               3
               4

In the code above “times” is a built in Groovy method exposed by integer object that accepts a closure and calls that closure 5 times. The trick to understand closure lies in how calling method in this case “times” calls the closure. In the case above “times” method executes 5 times, it means it calls the closure {param -> println param}  5 times, each time passing a parameter from 0 to 4. We will further explain the calling part later when we will code a custom method that accepts a closure and call the closure defined above. Since Groovy is all about cutting verbosity, it has a special short hand notation in case of closures having a single parameter. So instead of the code below:

 def a = {param -> println param}  

we could have defined the closure above like this

 def a = {println it}   

Note: the first parameter is implicit and can be accessed as “it” in the method body.

In functional languages many times closure can also be used as Lambda’s aka anonymous functions, and Groovy provides a very succinct syntax to define and call closure at the same time. So instead of first defining the closure and then passing it to times, we could have just written something like this:

 5.times {println it} //defining and passing the closure to the times method at the same time  

In order to understand how the closure is used and called from inside the calling method, let’s write our own custom function called “loop” that mimics “times” method above, and see how we can pass the closure to our custom method below:

 def loop(clsr) {  //a Groovy function that accepts a closure as a parameter   
    for (int i =0; i<5; i++)   
    clsr.call(i)  //calling a closure "clsr" with parameter i in a for loop  
 }  

Note: In the method above “clsr” is never defined as of type closure, but since Groovy is a dynamic language at run time the groovy binds the formal parameter to the supplied actual parameter which in our case is of type closure. 

Here are the ways we can call the method “loop” above which takes closure as an input parameter:

 def a = {param -> println param}   
 Loop (a)  
 def b = {println it}   
 loop (b)   
 loop {println it} // calling as anonymous function  

In rest of the article I show the reader the heavy use of closure in the GDK. The area of GDK cover will be collections, files, xml and sql.

Collections:


Code below shows the use of closure in List and HashMap:

 def list = [1,2,3,4,5,2] // Defines a list via Groovy literal syntax  
 list.find {value -> value == 2} // Call list “find” method with a closure   

or short hand notation

 list.find{it == 2}  

returns a list of [2,2]

 list.findAll{it % 2 == 0} // Call the “findAll” method of the list  

returns a list of all even numbers [2,4,2]

 list.findAll{it % 2 == 1} // that is how you return a list of odd numbers [1,3,5]  

So in the code above you see the sheer power of closure, where the findAll() method is coded in abstraction and the value return by the method depends on the caller passing the appropriate closure. Doesn’t it look like the command or strategy pattern without all the interfaces and contracts you have to adhere with?

 def hashmap = [a:1,b:2,c:3] //Defines a HashMap   
 hashmap.each {k,v -> println k println v}    

In the code above the each() method of hash map accepts a closure with 2  parameters in this case key and value (k,v) and returns the output: a 1 b 2 c 3.

File I/O:

The code below shows a typical use of closure in Groovy file object

 def file = new File (/C:\test.txt/)   
 file.eachLine{line,no -> println "${no}: ${line}" }   

The code above creates a file object and then passes a closure with 2 parameters (line and no) to eachLine()  method. The eachLine() method of file will call back the supplied closure with each line and a line number.

Another file example:

 def dir = new File (/C:\Users\xxxx\Documents/)  
 dir.eachFileRecurse() {println it}   

The code above creates a file object an then passes a closure to method eachFilerecurse(). The eachFilerecurse() callbacks the closure with all the files under a directory recursively. 

XML:

The code below shows how Groovy XML Parser and Node object utilizes the closure to print each node

 def xml = """  
 <Department type="Java Practice">  
  <employee>Rashid Jilani</employee>  
  <employee>Albert Yeghikian</employee>  
  <employee>David Wetzel</employee>  
 </Department>  
 """  
 def emp = new XmlParser().parseText(xml) //Returns a Node  
 println "type = ${emp.attribute("type")}"  
 emp.employee.each{ println it.text() }  
In the code above emp is a Node that  holds a list of employee that accepts a closure to print all the nodes under employee.

SQL:

The code below shows the typical use of closures in Groovy sql libraries.

 import groovy.sql.Sql  
 def sql = Sql.newInstance("jdbc:mysql://localhost:3306/sakila", "root",  
       "password", "com.mysql.jdbc.Driver")  
 new File(/C:\Users\rjilani\Documents\actor.txt/).withWriter { file ->   
 sql.eachRow("select * from actor") { println it.first_name + ' ' + it.last_name  
    file.writeLine(it.first_name + ' ' + it.last_name)  
   }  
 }  

In the code above withWriter() method accepts a closure and call back the closure with the file object that could be later used to write objects back to the file. Later eachRow() method of sql object accepts a query string and a closure, and call back the closure with each row of the returned resultset.

Hope you now have a better idea what a closure is and how to define code and call a closure. In my next blog I try to cover MOP features in Groovy.



4 comments:

  1. Hej, thank. Useful summary. I like Groovy.

    ReplyDelete
  2. For me it works only if I define loop as static.


    class clr {

    def static loop(clsr) { //a Groovy function that accepts a closure as a parameter

    for (int i =0; i<5; i++)
    clsr.call(i) //calling a closure "clsr" with parameter i in a for loop
    }
    public static void main (args){
    def a = {param -> println param}
    loop (a)
    def b = {println it}
    loop (b)
    loop {println it} // calling as anonymous function



    }


    }

    ReplyDelete
    Replies
    1. You must construct a clr object in order to call non-static method loop():

      class clr {

      def loop(clsr) { .... }

      public static void main(args) {
      clr c = new clr();
      ...
      c.loop(a)
      }

      Delete