This chapter covers
- Removing redundancy and verbosity with Groovy’s metaprogramming annotations
- Writing your own compiler extensions using the AST transformations feature
- Compile-time metaprogramming testing, tools, and pitfalls
It is my firm belief that all successful languages are grown and not merely designed from first principles.
Bjarne Stroustrup, The Design and Evolution of C++
The previous chapter covered dynamic programming with Groovy, where the behavior of a type or even an individual object can change while the program is executing. You don’t always need the behavior to vary that dynamically though—sometimes you want only to be able to apply common patterns in an expressive and efficient manner once and for all when the class is compiled.
This chapter covers compile-time metaprogramming or AST transformations. You’ll learn a bit about the concept and its importance. Then we’ll explore most of the transformations Groovy ships with, such as @ToString, @EqualsAndHashCode, and @Lazy, and show you how these keep your code lean and clean. Next, we’ll dive into more details about how AST transformations work and ways to create AST data structures. Then you’ll write your own local and global AST transformations before we look at tools available for viewing and testing AST data structures. As a final step, you’ll see some of the common mistakes and limitations encountered with compile-time metaprogramming.