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.

Do you want to know how to develop your skillset to 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!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


6 − = two



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
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