APPENDIX B: Introduction to Groovy 415
The return type and the return statement are not included in the body of the
method. Groovy always returns the results of the last expression—in this case,
the GString "Hello,.. .".
The access modifier public is not defined. Unless you specify otherwise, Groovy
defaults all classes, properties, and methods to public access.
Closures
Functional programming gives you the right foundation to think about concurrency on the basis
of underlying principles: referential transparency, higher-order functions, and immutable values.
Understanding these key elements is crucial to understanding closures (and other functional features
recently introduced in Groovy). Functional programming is built on the premise of pure functions. In
mathematics, functions are pure in that they lack side effects. Consider the classic function sin(x):
y = sin(x). No matter how many times sin(x) is called, no global or contextual state is modified
internally by sin(x). Such a function is pure, free of side effects, and oblivious to the context. This
obliviousness to the surrounding context is known as referential transparency. If no global state is
modified, concurrent invocation of the function is steadfast. In functional programming, functions
are first-class citizens, meaning functions can be assigned to variables, functions can be passed to
other functions, and functions can be returned as values from other functions. And such functions,
which take functions as arguments or return a function, are called higher-order functions.
Referential transparency, higher-order functions, and immutable values together make functional
programming a better way to write concurrent software. Though functional languages are all about
eliminating side effects, a language that never allowed for side effects would be useless. As a matter
of fact, introducing side effects is crucial to any language. All functional languages have to provide
mechanisms for introducing side effects in a controlled manner because even though functional
languages are about pure programming, a language that does not sanction side effects would be
useless because input and output are essentially the ramification of side effects.
Understanding Closures
One of the techniques to introduce side effects in a controlled manner is a closure. A closure
definition in Groovy follows this syntax:
{ [closure parameters ->] closure body}
where [closure parameters->] is an optional comma-delimited list of arguments, and the closure
body can be an expression as well as zero or more Groovy statements. The arguments look similar
to a method’s parameter list, and these arguments may be typed or untyped. A Groovy closure is
a block of reusable code within curly braces, {}, which can be assigned to a property or a variable
or passed as a parameter to a method. A closure is executed only when it is called, not when it is
defined. Listing B-25 illustrates this.