Groovy

Groovy Closure Example

1. Introduction

A closure is an anonymous code block that can take arguments, return value, and also can be assigned to a variable. When it comes to Groovy, a closure can contain a variable scope defined outside of the closure expression. Groovy offers extended features to formal closure definition.

By using this features, we can write our code more dynamically by applying closures to functions as parameter, caling anonymous code blocks inside functions, etc…. Let’s see closure in action with supporting examples.
 
 

2. Closure Declaration

ClosureDeclaration.groovy

package com.javacodegeeks.groovy.closure

class ClosureDeclaration {

	static main(args) {
		def myClosure = { println "Hello World!" }
		myClosure.call() // Hello World!
		myClosure() // Hello World!
	}

}

In this example, we have defined a closure on line 06, and then we have called it by using call() function. Alternatively, you can call closures by acting as function directly as on line 07

3. Closure Parameters

Sometimes, we need to pass arguments to the closures to make them more dynamically according to our needs. You can write a closure that accepts parameters while calling them. Let’s see following example to see how it works.

ClosureParameters.groovy

package com.javacodegeeks.groovy.closure

class ClosureParameters {

	static main(args) {
		
		def squareWithImplicitParameter = { it * it }
		println squareWithImplicitParameter(4) // 16
		
		def sumWithExplicitTypes = { int a, int b -> return a + b }
		println sumWithExplicitTypes(11, 8) // 19
		
		def sumWithOneExplicitOneOptionalTypes = { int a, b -> return a + b }
		println sumWithOneExplicitOneOptionalTypes(20, 13) // 33
		
		def sumWithDefaultParameterValue = { a, b = 5 -> return a + b }
		println sumWithDefaultParameterValue(4)  // 9
		
	}

}

On line 07, we have used implicit argument called it that defines default parameter provided to the closure. In square closure, we accessed the default parameter with it. Actually, it is equal to below code.

Square function without “it”

def square = {x -> x * x}
println square(4)

And this function takes only one parameter and returns the multiplication of the same number. Remember that, the last line in the functions returned as default in Groovy language. In ClosureParameters.groovy class on line 10, we have defined closure with 2 parameters and both of them has explicit types that is int. In same way, it takes two arguments and returns sum of them. You do not need to provide explicit types, you can use optional types in arguments also. When you look at line 13, you will see that a has type int, but b don’t. Groovy closures also support default parameter values. On line 16, you need to provide first argument, but if you do not provide second parameter, it will be 5 as default.

4. VarArgs

You can define variable argument in closures for accepting dynamic arguments to closures. Let’s have a look at following example to see how it works

ClosureVarArgs.groovy

package com.javacodegeeks.groovy.closure

class ClosureVarArgs {

	static main(args) {
		def combine = { String... names ->
			names.join(',') 
		}
		
		println combine('John', 'Doe', 'Betty') // John,Doe,Betty
	}

}

As you can see on line 06, we have defined a closure that takes variable arguments with String... names and we have joined them. Yes, you can also use array as one argument then join them, but this example is for showing how VarArgs can be used.

5. Closure Passing

You can pass closure as parameter to another closure easily. Let’s look at following example.

PassingClosure.groovy

package com.javacodegeeks.groovy.closure

class PassingClosure {

	static main(args) {
		def funcClosure = { x, func ->
			func(x)
		}
		
		println funcClosure([1, 2, 3], { it.size()}) // 3
	}

}

As you can see on line 06 there are two closure parameter, but they are not just a parameter like String or Integer. When you look at the closure body, we are using func(x). This means, func is an another closure that accepts closure expression. On line 10, funcClosure([1, 2, 3], { it.size()}), first parameter is a list and second parameter is a expression that uses it, and that means first parameter of the closure funcClosure

6. Closure Composition

In Groovy, you can compose different closures to simulate compound functions in Math science. In this section, we will simulate f(g(x)) = .... Let say that, you will sum two numbers and then you will apply square function to sum result. You can do that by following.

PassingClosure.groovy

package com.javacodegeeks.groovy.closure

class ClosureComposition {

	static main(args) {
		
		def sum = { a, b -> return a + b }
		def square = { it * it }
		def squareOfSum = square << sum
		
		println squareOfSum(2, 3) // 25
		
	}

}

On line 07, we defined sum closure and on line 08 square function. On line 09, we pass sum function to square function and actually it turns into following.

{ { a, b -> return a + b } * { a, b -> return a + b }}

7. Conclusion

Closures helps us to define anonymous-like functions in program to use that closure as parameter or function body. We can directly call it by using call(), or we can use it as parameter to another closure or function.

Download
You can download the full source code of this example as an  Eclipse project here: GroovyClosureExample

Huseyin Babal

Huseyin Babal has deep experience in Full Stack Development since 2007. He is mainly developing applications with JAVA, Spring, PHP, NodeJS, AngularJS. He is also interested in DevOps Engineering since 2013 and using AWS, Heroku for Cloud deployment and playing with Docker and Consul for implementing infinite scalable systems. He likes to share his experience in public conferences and perform advanced workshops about Full Stack Development and Devops. He is the author of NodeJS in Action course in Udemy.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button