Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 8 Next »

Want to learn some Groovy, but don't already know Java? This one's for you.

Run these examples inside a script. All code tested using Groovy v1.0.

If you already know Java, you can instead read "Closures for Java Programmers".


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 assign a sequence of statements that refers to its external context to a variable, then execute it later. It's 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:

When a closure doesn't explicitly refer to any part of its external context, it's correct name is "lambda block". However, because Groovy implements it in the same way as a closure, it's common to use the same name for both concepts:

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

We can pass one closure into another as a parameter:

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

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

Parameter Defaulting, Currying, and Number-Varying

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. (Object[] is an example of a 'type', to be explained in another lesson on Typing in Groovy.)

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:

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:


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. (If we use different 'types' of parameters, we can often have more than one function of the same name and same number of parameters. To be explained in another lesson on Groovy Typing.)

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

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:

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

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

  • No labels