6. Closures

Closures are a powerful feature in Magnolia Groovy Script, and they can be used in various ways. Let's go through some important use cases with examples:

Basic Closure

A closure is a block of code that can be assigned to a variable and executed later. Here's a basic example of a closure in Magnolia Groovy Script:

def sayHello = {
    println("Hello, Magnolia!")
}

// Execute the closure
sayHello()

Closure with Parameters

Closures can take parameters just like regular functions:

def greet = { name ->
    println("Hello, $name!")
}

// Execute the closure with a parameter
greet("Magnolia")

[Tip: Use the -> symbol to specify parameters in the closure.]

Closures as Arguments

You can pass closures as arguments to other functions. For example, you can use the each method on a list:

def numbers = [1, 2, 3, 4, 5]

numbers.each { num ->
    println("Number: $num")
}

[Tip: Closures are often used for concise and expressive code when working with collections.]

Returning Closures

Closures can also be returned from functions. Here's an example where a function returns a closure:

def createMultiplier = { factor ->
    return { value ->
        value * factor
    }
}

def doubleInput = createMultiplier(2)
println(doubleInput(5)) // Output: 10

[Tip: Returning closures can be useful for creating specialized functions on the fly.]

Closures with External Variables

Closures can capture external variables. This is called closure scoping:

def createCounter = {
    def count = 0
    return {
        count++
    }
}

def counter = createCounter()
println(counter()) // Output: 0
println(counter()) // Output: 1

[Tip: Closures can access variables from their enclosing scope even after the enclosing function has completed.]

Closure Composition

You can compose closures to create more complex behavior:

def add = { x, y -> x + y }
def multiply = { x, y -> x * y }

def calculate = { operation, x, y ->
    operation(x, y)
}

println(calculate(add, 3, 2))      // Output: 5
println(calculate(multiply, 3, 2)) // Output: 6

[Tip: Closure composition allows for flexible and reusable code.]