Groovy closures go beyond basic syntax and scope — they offer powerful functional programming features like currying, memoization, and composition. These techniques can help you write cleaner, more efficient, and more reusable code.
In this tutorial, you'll explore some advanced closure capabilities that unlock even more potential from Groovy scripts.
Preparation
Make sure Groovy is installed. You can use:
- SDKMAN (Linux/macOS):
sdk install groovy
- Groovy Console for interactive editing:
groovyConsole
Online editors like TutorialsPoint Groovy Editor https://www.tutorialspoint.com/compilers/online-groovy-compiler.htm
Save code in ClosureScopeExample.groovy and run with groovy ClosureScopeExample.groovy.
Currying in Groovy
Currying is the process of fixing several arguments to a function, producing another function of smaller arity (fewer parameters).
Example: Left Currying
def multiply = { a, b -> a * b }
def double = multiply.curry(2)
println double(5) // Output: 10
The double closure is a new function where a is always 2.
Right Currying
def triple = multiply.rcurry(3)
println triple(4) // Output: 12
Index Currying (Mid-position)
def divide = { a, b, c -> (a + b) / c }
def curried = divide.ncurry(1, 4) // Fix second argument (index 1) to 4
println curried(6, 2) // Output: 4.0
Memoization
Memoization caches closure results for improved performance with expensive operations.
Basic Memoization
def fib
fib = { n ->
if (n < 2) return n
fib(n - 1) + fib(n - 2)
}.memoize()
println fib(30) // Much faster due to caching
You can also use:
- .memoizeAtMost(n)
- .memoizeAtLeast(n)
- .memoizeBetween(min, max)
Closure Composition
Groovy allows you to compose closures for cleaner and modular transformations.
Example: Function Composition
def upper = { it.toUpperCase() }
def exclaim = { it + '!' }
def excited = upper >> exclaim
println excited('groovy') // Output: GROOVY!
- >> composes from left to right
- << composes from right to left
Trampolining (Avoiding Stack Overflow)
Trampolining allows recursion without blowing the stack by deferring evaluation.
def factorial
factorial = { n, acc = 1 ->
if (n == 1) return acc
return factorial.trampoline(n - 1, n * acc)
}.trampoline()
println factorial(1000) // Safe from StackOverflow
Closure as a Strategy
Closures are perfect for strategy patterns or dynamic behavior.
def taxStrategy = { amount -> amount * 0.2 }
def calculateTax = { amount, strategy -> strategy(amount) }
println calculateTax(100, taxStrategy) // Output: 20.0
Conclusion
In this tutorial, you've explored powerful features of advanced Groovy closures:
- Currying to create reusable partial functions
- Memoization to optimize performance
- Composition to build modular behavior
- Trampolining for safe recursion
These tools make Groovy an expressive and efficient language for both scripting and real-world applications.
Next, we’ll explore Groovy Closures in Real-World Scripts — where you'll apply closures to file processing, configuration, and more.
You can find the full source for this tutorial on our GitHub.
That just the basic. If you need more deep learning about Groovy and Grails you can take the following cheap course:
- Mastering Grails. A Comprehensive Grails Course.
- Groovy Scripting for Developers / Testers
- Introduction to JVM Languages Clojure, Kotlin, and Groovy
Thanks!