Closures in Groovy

Court-ClosureThe simpliest explanation of a closure in Groovy is that it is anonymous function.
 
 
 
 
 
 
 
 
 

def closure = { println "I am a closure" }
closure() // Prints I am a closure

Ok, so first point here is that I am a closure is not printed when the closure is defined but only when it is invoked. Closures facilitate delayed execution. It is also possible to pass parameters to a closure

def closureWithParameters = {x, y -> print(x  + " and " + y)}
closureWithParameters("Hello dudes", "Hello Mega Dude")  // Prints Hello dudes and Hello Mega Dude

When the closure has only one parameter, we don’t even need the -> we can just use the implicit it variable.

def closureWithParameters = { println it }
closureWithParameter("Hello dude")  // Prints Hello dude

Now, now, now kiddies. Closures don’t just exist in Groovy, they exist in many languages and one of their features that people sometimes forget about is that they contain a representation of the function’s lexical environment. In English, this means they get a snapshot of the context in which they are defined and only they they can access this snapshot and change it. In JavaScript, we can do something like this:

function outerFuntion () {
    var counter = 1;
    function innerFunction() {
        alert("Counter=" + counter++);
    }   
    return innerFunction;
}

Even though counter is defined in outerFunction() as a local variable, it is considered to be in innerFunction()’s lexical environment hence it can access it. When innerFunction() is returned as a closure it will get its own value of it that only it can access. So if we were to do this:

var myClosure = outerFuntion();  // myFunc is now a pointer to the innerFunction closure.
myClosure();  // Executes Counter=1;

First, outerFunction() is executed and it returns the innerFunction closure. The variable is assigned to this closure. Now, now, now, note the key word here is “returned”. innerFunction() is returned, it is not executed. So again we see the delay of execution characteristic of closures. Everytime we then execute the closure, the counter is increased.

myClosure();  // Executes Counter=2;
myClosure();  // Executes Counter=3;
myClosure();  // Executes Counter=4;
myClosure();  // Executes Counter=5;
myClosure();  // Executes Counter=6;

So the closure has state, that it remembers across invocations. That state begins as the snapshot of the context in which the function is defined and it is something that only they closure can change. So yeah that’s the key point of closures. They are a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of variables that were in-scope at the time that the closure was created. Ok, so back onto Groovy. The same example would look like:

def outerFunction () {
    def counter = 1;
    return {
        print "Counter=" + counter++
    }
}
def myClosure = outerFunction()

myClosure();  // executes 1 
myClosure();  // executes 2
myClosure();  // executes 3 
myClosure();  // executes 4
myClosure();  // executes 5 
myClosure();  // executes 6

It’s very similar to the JavaScript example. The word def is used instead of function. We just also make use of the fact you don’t have to use the word function in Groovy when you want define an anonymous function. If we wanted to make the inner function anonymous in the JavaScript version we could do:

function outerFuntion () {
    var counter = 1; 
    return function () {
        alert("Counter=" + counter++);
    };
}

var myClosure = outerFuntion();  // myFunc is now a pointer to the innerFunction closure.
myClosure();  // Executes Counter=1;
myClosure();  // Executes Counter=2;

But still have to use the word function, we just don’t have to give it a name. Ok, so until the next time take care of yourselves.
 

Reference: Closures in Groovy from our JCG partner Alex Staveley at the Dublin’s Tech Blog blog.
Related Whitepaper:

Java Essential Training

Author David Gassner explores Java SE (Standard Edition), the language used to build mobile apps for Android devices, enterprise server applications, and more!

The course demonstrates how to install both Java and the Eclipse IDE and dives into the particulars of programming. The course also explains the fundamentals of Java, from creating simple variables, assigning values, and declaring methods to working with strings, arrays, and subclasses; reading and writing to text files; and implementing object oriented programming concepts. Exercise files are included with the course.

Get it Now!  

Leave a Reply


× 6 = forty eight



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close