JN2515-Closures Add comment to Wiki View in Wiki Edit Wiki page Printable Version


We can embed a sequence of statements inside "try", called a "block". Defined variables are only visible within that block, not outside:

Using the "def" keyword is optional because we are inside a script:

But variables without "def" are visible outside the block:

We can't define a variable (using "def") with the same name as another already visible (ie, another "in scope"):

We can nest blocks:


We can take a sequence of statements that refers to its external context and assign it to a variable, then execute it later. It's technically called a "closable block", commonly called a "closure":

The closure assigned to the variable (here, c) will remember its context (here, including a) even if that context is not in scope when the closure is called:

A closure always returns a value, the result of its last statement:

By putting a closure within another, we can create two instances of it:

Closure Parameters

We can put parameters at the beginning of a closure definition, and pass values in when we call the closure:

We can also pass information out using the parameters:

One parameter is always available, called "it", if no explicit parameters are named:

If parameters aren't specified, "it" will still be implicitly defined, but be null:

Parameters can't have the same name as another variable in scope, except for the implicit parameter 'it':

If there's already a variable called 'it' in scope, we can access it using owner.it:

We can pass one closure into another as a parameter:

We can return a closure from another:

There's a shortcut syntax when explicitly defining a closure within another closure call, where that closure is the last or only parameter:

Arguments in a closure call can be named. They are interpreted as the keys in a map passed in as the first parameter:

We can enquire the number of parameters for a closure, both from inside and outside the closure:

A closure may have its last parameter/s assigned default value/s:

A closure can take a varying number of arguments by prefixing its last parameter with Object[], and accessing them using 'each':

We can also prefix the last parameter of a closure with Closure[] to pass in a varying number of other closures, even using the shortcut syntax:

When we call a closure with a list argument, if there's no closure defined with a list parameter, the arguments are passed in as separate parameters:

A closure may be copied with its first parameter/s fixed to a constant value/s, using curry:

In closures, we can use currying and parameter-count-varying together:

We can make closures recursive:

We can even make a recursion of anonymous closures (thanks to 'call' method available for each closure)


A function is similar to a closure, though a function can't access defined variables in its surrounding context:

The def keyword is compulsory when defining functions:

We use a special syntax to assign a function to another variable when using the original definition name:

Unlike blocks and closures, we can't nest functions:

Function Parameters

A function can have parameters, with which we can pass information both in and out:

We can have more than one function of the same name if they each have different numbers of (untyped) parameters.

A function returns a value, unless prefixed by void instead of def, when it always returns null:

When there's a method and closure with the same name and parameters, the method is chosen instead of the closure:

Some Similarities with Closures

We can use the shortcut invocation syntax for closure parameters:

A function may have its last parameter/s assigned default value/s:

Arguments in a function call can be named, interpreted as keys in a map passed in as first parameter:

A function can take a varying number of arguments by prefixing its last argument by Object[], and accessing them using each:

When we call a function with a list argument, if there's none defined with a list parameter, the arguments are passed in separately:

We can call a function recursively by referencing its own name:



Results of your search request can come from various sources: the Groovy website itself, the JIRA issues, the API documentation, as well as a few other interesting Groovy-related blogs.

  By  -  pages  -  views  - last modified