# Semantics

version 2.3.7

This chapter covers the semantics of the Groovy programming language.

## 1. Statements

### 1.1. Variable definition

Variables can be defined using either their type (like `String`) or by using the keyword `def`:

    String x
    def o

`def` is a replacement for a type name. In variable definitions it is used to indicate that you don’t care about the type. In variable definitions it is mandatory to either provide a type name explicitly or to use "def" in replacement. This is needed to the make variable definitions detectable for the Groovy parser.

You can think of `def` as an alias of `Object` and you will understand it in an instant.

| Variable definition types can be refined by using generics, like in `List<String> names`. To learn more about the generics support, please read the generics section.

### 1.2. Variable assignment

You can assign values to variables for later use. Try the following:

    x = 1
    println x

    x = new java.util.Date()
    println x

    x = -3.1499392
    println x

    x = false
    println x

    x = "Hi"
    println x

#### 1.2.1. Multiple assignment

Groovy supports multiple assignment, i.e. where multiple variables can be assigned at once, e.g.:

    def (a, b, c) = [10, 20, 'foo']
    assert a == 10 && b == 20 && c == 'foo'

You can provide types as part of the declaration if you wish:

    def (int i, String j) = [10, 'foo']
    assert i == 10 && j == 'foo'

As well as used when declaring variables it also applies to existing variables:

    def nums = [1, 3, 5]
    def a, b, c
    (a, b, c) = nums
    assert a == 1 && b == 3 && c == 5

The syntax works for arrays as well as lists, as well as methods that return either of these:

    def (_, month, year) = "18th June 2009".split()
    assert "In $month of $year" == 'In June of 2009'

#### 1.2.2. Overflow and Underflow

If the left hand side has too many variables, excess ones are filled with null’s:

    def (a, b, c) = [1, 2]
    assert a == 1 && b == 2 && c == null

If the right hand side has too many variables, the extra ones are ignored:

    def (a, b) = [1, 2, 3]
    assert a == 1 && b == 2

#### 1.2.3. Object destructuring with multiple assignment

In the section describing the various Groovy operators, the case of the subscript operator has been covered, explaining how you can override the `getAt()`/`putAt()` method.

With this technique, we can combine multiple assignments and the subscript operator methods to implement object destructuring.

Consider the following immutable `Coordinates` class, containing a pair of longitude and latitude doubles, and notice our implementation of the `getAt()` method:

    @Immutable
    class Coordinates {
        double latitude
        double longitude

        double getAt(int idx) {
            if (idx == 0) latitude
            else if (idx == 1) longitude
            else throw new Exception("Wrong coordinate index, use 0 or 1")
        }
    }

Now let’s instantiate this class and destructure its longitude and latitude:

    def coordinates = new Coordinates(latitude: 43.23, longitude: 3.67) (1)

    def (la, lo) = coordinates                                          (2)

    assert la == 43.23                                                  (3)
    assert lo == 3.67

1 | we create an instance of the `Coordinates` class
2 | then, we use a multiple assignment to get the individual longitude and latitude values
3 | and we can finally assert their values.

### 1.3. Control structures (WIP)

#### 1.3.1. Conditional structures

##### if / else

Groovy supports the usual if - else syntax from Java

    def x = false
    def y = false

    if ( !x ) {
        x = true
    }

    assert x == true

    if ( x ) {
        x = false
    } else {
        y = true
    }

    assert x == y

Groovy also supports the normal Java "nested" if then else if syntax:

    if ( ... ) {
        ...
    } else if (...) {
        ...
    } else {
        ...
    }

##### switch / case

The switch statement in Groovy is backwards compatible with Java code; so you can fall through cases sharing the same code for multiple matches.

One difference though is that the Groovy switch statement can handle any kind of switch value and different kinds of matching can be performed.

    def x = 1.23
    def result = ""

    switch ( x ) {
        case "foo":
            result = "found foo"
            // lets fall through

        case "bar":
            result += "bar"

        case [4, 5, 6, 'inList']:
            result = "list"
            break

        case 12..30:
            result = "range"
            break

        case Integer:
            result = "integer"
            break

        case Number:
            result = "number"
            break

        case ~/fo*/: // toString() representation of x matches the pattern?
            result = "foo regex"
            break

        case { it < 0 }: // or { x < 0 }
            result = "negative"
            break

        default:
            result = "default"
    }

    assert result == "number"

Switch supports the following kinds of comparisons:

- Class case values matches if the switch value is an instance of the class

- Regular expression case values match if the `toString()` representation of the switch value matches the regex

- Collection case values match if the switch value is contained in the collection. This also includes ranges (since they are Lists)

- Closure case values match if the calling the closure returns a result which is true according to the Groovy truth

- If none of the above are used then the case value matches if the case value equals the switch value

| `default` must go at the end of the switch/case. While in Java the default can be placed anywhere in the switch/case, the default in Groovy is used more as an else than assigning a default case.

| when using a closure case value, the default `it` parameter is actually the switch value (in our example, variable `x`)

#### 1.3.2. Looping structures

##### Classic for loop

Groovy supports the standard Java / C for loop:

    String message = ''
    for (int i = 0; i < 5; i++) {
        message += 'Hi '
    }
    assert message == 'Hi Hi Hi Hi Hi '

##### for in loop

The for loop in Groovy is much simpler and works with any kind of array, collection, Map, etc.

    // iterate over a range
    def x = 0
    for ( i in 0..9 ) {
        x += i
    }
    assert x == 45

    // iterate over a list
    x = 0
    for ( i in [0, 1, 2, 3, 4] ) {
        x += i
    }
    assert x == 10

    // iterate over an array
    def array = (0..4).toArray()
    x = 0
    for ( i in array ) {
        x += i
    }
    assert x == 10

    // iterate over a map
    def map = ['abc':1, 'def':2, 'xyz':3]
    x = 0
    for ( e in map ) {
        x += e.value
    }
    assert x == 6

    // iterate over values in a map
    x = 0
    for ( v in map.values() ) {
        x += v
    }
    assert x == 6

    // iterate over the characters in a string
    def text = "abc"
    def list = []
    for (c in text) {
        list.add(c)
    }
    assert list == ["a", "b", "c"]

| Groovy also supports the Java colon variation with colons: `for (char c : text) {}`, where the type of the variable is mandatory.

##### while loop

Groovy supports the usual while {…} loops like Java:

    def x = 0
    def y = 5

    while ( y-- > 0 ) {
        x++
    }

    assert x == 5

#### 1.3.3. Exception handling

Exception handling is the same as Java.

#### 1.3.4. try / catch / finally

You can specify a complete `try-catch-finally`, a `try-catch`, or a `try-finally` set of blocks.

| Braces are required around each block’s body.

    try {
        'moo'.toLong()   // this will generate an exception
        assert false     // asserting that this point should never be reached
    } catch ( e ) {
        assert e in NumberFormatException
    }

We can put code within a finally clause following a matching try clause, so that regardless of whether the code in the try clause throws an exception, the code in the finally clause will always execute:

    def z
    try {
        def i = 7, j = 0
        try {
            def k = i / j
            assert false        //never reached due to Exception in previous line
        } finally {
            z = 'reached here'  //always executed even if Exception thrown
        }
    } catch ( e ) {
        assert e in ArithmeticException
        assert z == 'reached here'
    }

#### 1.3.5. Multi-catch

With the multi catch block (since Groovy 2.0), we’re able to define several exceptions to be catch and treated by the same catch block:

    try {
        /* ... */
    } catch ( IOException | NullPointerException e ) {
        /* one block to handle 2 exceptions */
    }

### 1.4. Power assertion (TBD)

### 1.5. Labeled statements (TBD)

## 2. Expressions (TBD)

### 2.1. GPath expressions (TBD)

## 3. Promotion and coercion (TBD)

### 3.1. Number promotion (TBD)

### 3.2. Closure to type coercion

#### 3.2.1. Assigning a closure to a SAM type

A SAM type is a type which defines a single abstract method. This includes:

Functional interfaces

    interface Predicate<T> {
        boolean accept(T obj)
    }

Abstract classes with single abstract method

    abstract class Greeter {
        abstract String getName()
        void greet() {
            println "Hello, $name"
        }
    }

Any closure can be converted into a SAM type using the `as` operator:

    Predicate filter = { it.contains 'G' } as Predicate
    assert filter.accept('Groovy') == true

    Greeter greeter = { 'Groovy' } as Greeter
    greeter.greet()

However, the `as Type` expression is optional since Groovy 2.2.0. You can omit it and simply write:

    Predicate filter = { it.contains 'G' }
    assert filter.accept('Groovy') == true

    Greeter greeter = { 'Groovy' }
    greeter.greet()

which means you are also allowed to use method pointers, as shown in the following example:

    boolean doFilter(String s) { s.contains('G') }

    Predicate filter = this.&doFilter
    assert filter.accept('Groovy') == true

    Greeter greeter = GroovySystem.&getVersion
    greeter.greet()

#### 3.2.2. Calling a method accepting a SAM type with a closure

The second and probably more important use case for closure to SAM type coercion is calling a method which accepts a SAM type. Imagine the following method:

    public <T> List<T> filter(List<T> source, Predicate<T> predicate) {
        source.findAll { predicate.accept(it) }
    }

Then you can call it with a closure, without having to create an explicit implementation of the interface:

    assert filter(['Java','Groovy'], { it.contains 'G'} as Predicate) == ['Groovy']

But since Groovy 2.2.0, you are also able to omit the explicit coercion and call the method as if it used a closure:

    assert filter(['Java','Groovy']) { it.contains 'G'} == ['Groovy']

As you can see, this has the advantage of letting you use the closure syntax for method calls, that is to say put the closure outside of the parenthesis, improving the readability of your code.

#### 3.2.3. Closure to arbitrary type coercion

In addition to SAM types, a closure can be coerced to any type and in particular interfaces. Let’s define the following interface:

    interface FooBar {
        int foo()
        void bar()
    }

You can coerce a closure into the interface using the `as` keyword:

    def impl = { println 'ok'; 123 } as FooBar

This produces a class for which all methods are implemented using the closure:

    assert impl.foo() == 123
    impl.bar()

But it is also possible to coerce a closure to any class. For example, we can replace the `interface` that we defined with `class` without changing the assertions:

    class FooBar {
        int foo() { 1 }
        void bar() { println 'bar' }
    }

    def impl = { println 'ok'; 123 } as FooBar

    assert impl.foo() == 123
    impl.bar()

### 3.3. Map to type coercion

Usually using a single closure to implement an interface or a class with multiple methods is not the way to go. As an alternative, Groovy allows you to coerce a map into an interface or a class. In that case, keys of the map are interpreted as method names, while the values are the method implementation. The following example illustrates the coercion of a map into an `Iterator`:

    def map
    map = [
      i: 10,
      hasNext: { map.i > 0 },
      next: { map.i-- },
    ]
    def iter = map as Iterator

Of course this is a rather contrived example, but illustrates the concept. You only need to implement those methods that are actually called, but if a method is called that doesn’t exist in the map a `MissingMethodException` or an `UnsupportedOperationException` is thrown, depending on the arguments passed to the call, as in the following example:

    interface X {
        void f()
        void g(int n)
        void h(String s, int n)
    }

    x = [ f: {println "f called"} ] as X
    x.f() // method exists
    x.g() // MissingMethodException here
    x.g(5) // UnsupportedOperationException here

The type of the exception depends on the call itself:

- `MissingMethodException` if the arguments of the call do not match those from the interface/class

- `UnsupportedOperationException` if the arguments of the call match one of the overloaded methods of the interface/class

### 3.4. String to enum coercion

Groovy allows transparent `String` (or `GString`) to enum values coercion. Imagine you define the following enum:

    enum State {
        up,
        down
    }

then you can assign a string to the enum without having to use an explicit `as` coercion:

    State st = 'up'
    assert st == State.up

It is also possible to use a `GString` as the value:

    def val = "up"
    State st = "${val}"
    assert st == State.up

However, this would throw a runtime error (`IllegalArgumentException`):

    State st = 'not an enum value'

Note that it is also possible to use implicit coercion in switch statements:

    State switchState(State st) {
        switch (st) {
            case 'up':
                return State.down // explicit constant
            case 'down':
                return 'up' // implicit coercion for return types
        }
    }

in particular, see how the `case` use string constants. But if you call a method that uses an enum with a `String` argument, you still have to use an explicit `as` coercion:

    assert switchState('up' as State) == State.down
    assert switchState(State.down) == State.up

### 3.5. Custom type coercion

It is possible for a class to define custom coercion strategies by implementing the `asType` method. Custom coercion is invoked using the `as` operator and is never implicit. As an example, imagine you defined two classes, `Polar` and `Cartesian`, like in the following example:

    class Polar {
        double r
        double phi
    }
    class Cartesian {
       double x
       double y
    }

And that you want to convert from polar coordinates to cartesian coordinates. One way of doing this is to define the `asType` method in the `Polar` class:

    def asType(Class target) {
        if (Cartesian==target) {
            return new Cartesian(x: r*cos(phi), y: r*sin(phi))
        }
    }

which allows you to use the `as` coercion operator:

    def sigma = 1E-16
    def polar = new Polar(r:1.0,phi:PI/2)
    def cartesian = polar as Cartesian
    assert abs(cartesian.x-sigma) < sigma

Putting it all together, the `Polar` class looks like this:

    class Polar {
        double r
        double phi
        def asType(Class target) {
            if (Cartesian==target) {
                return new Cartesian(x: r*cos(phi), y: r*sin(phi))
            }
        }
    }

but it is also possible to define `asType` outside of the `Polar` class, which can be practical if you want to define custom coercion strategies for "closed" classes or classes for which you don’t own the source code, for example using a metaclass:

    Polar.metaClass.asType = { Class target ->
        if (Cartesian==target) {
            return new Cartesian(x: r*cos(phi), y: r*sin(phi))
        }
    }

### 3.6. Class literals vs variables and the as operator

Using the `as` keyword is only possible if you have a static reference to a class, like in the following code:

    interface Greeter {
        void greet()
    }
    def greeter = { println 'Hello, Groovy!' } as Greeter // Greeter is known statically
    greeter.greet()

But what if you get the class by reflection, for example by calling `Class.forName`?

    Class clazz = Class.forName('Greeter')

Trying to use the reference to the class with the `as` keyword would fail:

    greeter = { println 'Hello, Groovy!' } as clazz
    // throws:
    // unable to resolve class clazz
    // @ line 9, column 40.
    //   greeter = { println 'Hello, Groovy!' } as clazz

It is failing because the `as` keyword only works with class literals. Instead, you need to call the `asType` method:

    greeter = { println 'Hello, Groovy!' }.asType(clazz)
    greeter.greet()

## 4. Optionality (TBD)

### 4.1. Optional parentheses (TBD)

### 4.2. Optional semicolons (TBD)

### 4.3. Optional return keyword (TBD)

### 4.4. Optional public keyword (TBD)

## 5. The Groovy Truth (TBD)

### 5.1. Customizing the truth with asBoolean() methods (TBD)

## 6. Typing (WIP)

### 6.1. Optional typing

Optional typing is the idea that a program can work even if you don’t put an explicit type on a variable. Being a dynamic language, Groovy naturally implements that feature, for example when you declare a variable:

    String aString = 'foo'                      (1)
    assert aString.toUpperCase()                (2)

1 | `foo` is declared using an explicit type, `String`
2 | we can call the `toUpperCase` method on a `String`

Groovy will let you write this instead:

    def aString = 'foo'                         (1)
    assert aString.toUpperCase()                (2)

1 | `foo` is declared using `def`
2 | we can still call the `toUpperCase` method, because the type of `aString` is resolved at runtime

So it doesn’t matter that you use an explicit type here. It is in particular interesting when you combine this feature with static type checking, because the type checker performs type inference.

Likewise, Groovy doesn’t make it mandatory to declare the types of a parameter in a method:

    String concat(String a, String b) {
        a+b
    }
    assert concat('foo','bar') == 'foobar'

can be rewritten using `def` as both return type and parameter types, in order to take advantage of duck typing, as illustrated in this example:

    def concat(def a, def b) {                              (1)
        a+b
    }
    assert concat('foo','bar') == 'foobar'                  (2)
    assert concat(1,2) == 3                                 (3)

1 | both the return type and the parameter types use `def`
2 | it makes it possible to use the method with `String`
3 | but also with `int`s since the `plus` method is defined

| Using the `def` keyword here is recommanded to describe the intent of a method which is supposed to work on any type, but technically, we could use `Object` instead and the result would be the same: `def` is, in Groovy, strictly equivalent to using `Object`.

Eventually, the type can be removed altogether from both the return type and the descriptor. But if you want to remove it from the return type, you then need to add an explicit modifier for the method, so that the compiler can make a difference between a method declaration and a method call, like illustrated in this example:

    private concat(a,b) {                                   (1)
        a+b
    }
    assert concat('foo','bar') == 'foobar'                  (2)
    assert concat(1,2) == 3                                 (3)

1 | if we want to omit the return type, an explicit modifier has to be set.
2 | it is still possible to use the method with `String`
3 | and also with `int`s

| Omitting types is in general considered a bad practice in method parameters or method return types for public APIs. While using `def` in a local variable is not really a problem because the visibility of the variable is limited to the method itself, while set on a method parameter, `def` will be converted to `Object` in the method signature, making it difficult for users to know which is the expected type of the arguments. This means that you should limit this to cases where you are explicitly relying on duck typing.

### 6.2. Static type checking

By default, Groovy performs minimal type checking at compile time. Since it is primarily a dynamic language, most checks that a static compiler would normally do aren’t possible at compile time. A method added via runtime metaprogramming might alter a class or object’s runtime behavior. Let’s illustrate why in the following example:

    class Person {                                                          (1)
        String firstName
        String lastName
    }
    def p = new Person(firstName: 'Raymond', lastName: 'Devos')             (2)
    assert p.formattedName == 'Raymond Devos'                               (3)

1 | the `Person` class only defines two properties, `firstName` and `lastName`
2 | we can create an instance of Person
3 | and call a method named `formattedName`

It is quite common in dynamic languages for code such as the above example not to throw any error. How can this be? In Java, this would typically fail at compile time. However, in Groovy, it will not fail at compile time, and if coded correctly, will also not fail at runtime. In fact, to make this work at runtime, one possibility is to rely on runtime metaprogramming. So just adding this line after the declaration of the `Person` class is enough:

    Person.metaClass.getFormattedName = { "$delegate.firstName $delegate.lastName" }

This means that in general, in Groovy, you can’t make any assumption about the type of an object beyond its declaration type, and even if you know it, you can’t determine at compile time what method will be called, or which property will be retrieved, and this is perfectly fine. This is how dynamic languages work, and it has a lot of interest.

However, if your program doesn’t rely on dynamic features and that you come from the static world (in particular, from a Java mindset), not catching such "errors" at compile time can be surprising. As we have seen in the previous example, the compiler cannot be sure this is an error. To make it aware that it is, you have to explicitly instruct the compiler that you are switching to a type checked mode. This can be done by annotating a class or a method with `@groovy.lang.TypeChecked`.

When type checking is activated, the compiler performs much more work:

- type inference is activated, meaning that even if you use `def` on a local variable for example, the type checker will be able to infer the type of the variable from the assignments

- method calls are resolved at compile time, meaning that if a method is not declared on a class, the compiler will throw an error

- in general, all the compile time errors that you are used to find in a static language will appear: method not found, property not found, incompatible types for method calls, number precision errors, …

In this section, we will describe the behavior of the type checker in various situations and explain the limits of using `@TypeChecked` on your code.

#### 6.2.1. The `@TypeChecked` annotation

##### Activating type checking at compile time

The `groovy.lang.TypeChecked` annotation enabled type checking. It can be placed on a class:

    @groovy.transform.TypeChecked
    class Calculator {
        int sum(int x, int y) { x+y }
    }

Or on a method:

    class Calculator {
        @groovy.transform.TypeChecked
        int sum(int x, int y) { x+y }
    }

In the first case, all methods, properties, fields, inner classes, … of the annotated class will be type checked, whereas in the second case, only the method and potential closures or anonymous inner classes that it contains will be type checked.

##### Skipping sections

The scope of type checking can be restricted. For example, if a class is type checked, you can instruct the type checker to skip a method by annotating it with `@TypeChecked(TypeCheckingMode.SKIP)`:

    import groovy.transform.TypeChecked
    import groovy.transform.TypeCheckingMode

    @TypeChecked                                        (1)
    class GreetingService {
        String greeting() {                             (2)
            doGreet()
        }

        @TypeChecked(TypeCheckingMode.SKIP)             (3)
        private String doGreet() {
            def b = new SentenceBuilder()
            b.Hello.my.name.is.John                     (4)
            b
        }
    }
    def s = new GreetingService()
    assert s.greeting() == 'Hello my name is John'

1 | the `GreetingService` class is marked as type checked
2 | so the `greeting` method is automatically type checked
3 | but `doGreet` is marked with `SKIP`
4 | the type checker doesn’t complain about missing properties here

In the previous example, `SentenceBuilder` relies on dynamic code. There’s no real `Hello` method or property, so the type checker would normally complain and compilation would fail. Since the method that uses the builder is marked with `TypeCheckingMode.SKIP`, type checking is skipped for this method, so the code will compile, even if the rest of the class is type checked.

The following sections describe the semantics of type checking in Groovy.

#### 6.2.2. Type checking assignments

An object `o` of type `A` can be assigned to a variable of type `T` if and only if:

- `T` equals `A`

      Date now = new Date()

- or `T` is one of `String`, `boolean`, `Boolean` or `Class`

      String s = new Date() // implicit call to toString
      Boolean boxed = 'some string'       // Groovy truth
      boolean prim = 'some string'        // Groovy truth
      Class clazz = 'java.lang.String'    // class coercion

- or `o` is null and `T` is not a primitive type

      String s = null         // passes
      int i = null            // fails

- or `T` is an array and `A` is an array and the component type of `A` is assignable to the component type of `B`

      int[] i = new int[4]        // passes
      int[] i = new String[4]     // fails

- or `T` is an array and `A` is a list and the component type of `A` is assignable to the component type of `B`

      int[] i = [1,2,3]               // passes
      int[] i = [1,2, new Date()]     // fails

- or `T` is a superclass of `A`

      AbstractList list = new ArrayList()     // passes
      LinkedList list = new ArrayList()       // fails

- or `T` is an interface implemented by `A`

      List list = new ArrayList()             // passes
      RandomAccess list = new LinkedList()    // fails

- or `T` or `A` are a primitive type and their boxed types are assignable

      int i = 0
      Integer bi = 1
      int x = new Integer(123)
      double d = new Float(5f)

- or `T` extends `groovy.lang.Closure` and `A` is a SAM-type (single abstract method type)

      Runnable r = { println 'Hello' }
      interface SAMType {
          int doSomething()
      }
      SAMType sam = { 123 }
      assert sam.doSomething() == 123
      abstract class AbstractSAM {
          int calc() { 2* value() }
          abstract int value()
      }
      AbstractSAM c = { 123 }
      assert c.calc() == 246

- or `T` and `A` derive from `java.lang.Number` and conform to the following table

Table 1. Number types (java.lang.XXX)
T | A | Examples
--- | --- | ---
Double | Any but BigDecimal or BigInteger |
    Double d1 = 4d
    Double d2 = 4f
    Double d3 = 4l
    Double d4 = 4i
    Double d5 = (short) 4
    Double d6 = (byte) 4
Float | Any type but BigDecimal, BigInteger or Double |
    Float f1 = 4f
    Float f2 = 4l
    Float f3 = 4i
    Float f4 = (short) 4
    Float f5 = (byte) 4
Long | Any type but BigDecimal, BigInteger, Double or Float |
    Long l1 = 4l
    Long l2 = 4i
    Long l3 = (short) 4
    Long l4 = (byte) 4
Integer | Any type but BigDecimal, BigInteger, Double, Float or Long |
    Integer i1 = 4i
    Integer i2 = (short) 4
    Integer i3 = (byte) 4
Short | Any type but BigDecimal, BigInteger, Double, Float, Long or Integer |
    Short s1 = (short) 4
    Short s2 = (byte) 4
Byte | Byte |
    Byte b1 = (byte) 4

#### 6.2.3. List and map constructors

In addition to the assignment rules above, if an assignment is deemed invalid, in type checked mode, a list literal or a map literal `A` can be assigned to a variable of type `T` if:

- the assignment is a variable declaration and `A` is a list literal and `T` has a constructor whose parameters match the types of the elements in the list literal

- the assignment is a variable declaration and `A` is a map literal and `T` has a no-arg constructor and a property for each of the map keys

For example, instead of writing:

    @groovy.transform.TupleConstructor
    class Person {
        String firstName
        String lastName
    }
    Person classic = new Person('Ada','Lovelace')

You can use a "list constructor":

    Person list = ['Ada','Lovelace']

or a "map constructor":

    Person map = [firstName:'Ada', lastName:'Lovelace']

If you use a map constructor, additional checks are done on the keys of the map to check if a property of the same name is defined. For example, the following will fail at compile time:

    @groovy.transform.TupleConstructor
    class Person {
        String firstName
        String lastName
    }
    Person map = [firstName:'Ada', lastName:'Lovelace', age: 24]     (1)

1 | The type checker will throw an error `No such property: age for class: Person` at compile time

#### 6.2.4. Method resolution

In type checked mode, methods are resolved at compile time. Resolution works by name and arguments. The return type is irrelevant to method selection. Types of arguments are matched against the types of the parameters following those rules:

An argument `o` of type `A` can be used for a parameter of type `T` if and only if:

- `T` equals `A`

      int sum(int x, int y) {
          x+y
      }
      assert sum(3,4) == 7

- or `T` is a `String` and `A` is a `GString`

      String format(String str) {
          "Result: $str"
      }
      assert format("${3+4}") == "Result: 7"

- or `o` is null and `T` is not a primitive type

      String format(int value) {
          "Result: $value"
      }
      assert format(7) == "Result: 7"
      format(null)           // fails

- or `T` is an array and `A` is an array and the component type of `A` is assignable to the component type of `B`

      String format(String[] values) {
          "Result: ${values.join(' ')}"
      }
      assert format(['a','b'] as String[]) == "Result: a b"
      format([1,2] as int[])              // fails

- or `T` is a superclass of `A`

      String format(AbstractList list) {
          list.join(',')
      }
      format(new ArrayList())              // passes
      String format(LinkedList list) {
          list.join(',')
      }
      format(new ArrayList())              // fails

- or `T` is an interface implemented by `A`

      String format(List list) {
          list.join(',')
      }
      format(new ArrayList())                  // passes
      String format(RandomAccess list) {
          'foo'
      }
      format(new LinkedList())                 // fails

- or `T` or `A` are a primitive type and their boxed types are assignable

      int sum(int x, Integer y) {
          x+y
      }
      assert sum(3, new Integer(4)) == 7
      assert sum(new Integer(3), 4) == 7
      assert sum(new Integer(3), new Integer(4)) == 7
      assert sum(new Integer(3), 4) == 7

- or `T` extends `groovy.lang.Closure` and `A` is a SAM-type (single abstract method type)

      interface SAMType {
          int doSomething()
      }
      int twice(SAMType sam) { 2*sam.doSomething() }
      assert twice { 123 } == 246
      abstract class AbstractSAM {
          int calc() { 2* value() }
          abstract int value()
      }
      int eightTimes(AbstractSAM sam) { 4*sam.calc() }
      assert eightTimes { 123 } == 984

- or `T` and `A` derive from `java.lang.Number` and conform to the same rules as assignment of numbers

If a method with the appropriate name and arguments is not found at compile time, an error is thrown. The difference with "normal" Groovy is illustrated in the following example:

    class MyService {
        void doSomething() {
            printLine 'Do something'            (1)
        }
    }

1 | `printLine` is an error, but since we’re in a dynamic mode, the error is not caught at compile time

The example above shows a class that Groovy will be able to compile. However, if you try to create an instance of `MyService` and call the `doSomething` method, then it will fail at runtime, because `printLine` doesn’t exist. Of course, we already showed how Groovy could make this a perfectly valid call, for example by catching `MethodMissingException` or implementing a custom meta-class, but if you know you’re not in such a case, `@TypeChecked` comes handy:

    class MyService {
        void doSomething() {
            printLine 'Do something'            (1)
        }
    }

1 | `printLine` is this time a compile-time error

Just adding `@TypeChecked` will trigger compile time method resolution. The type checker will try to find a method `printLine` accepting a `String` on the `MyService` class, but cannot find one. It will fail compilation with the following message:

`Cannot find matching method MyService#printLine(java.lang.String)`

| It is important to understand the logic behind the type checker: it is a compile-time check, so by definition, the type checker is not aware of any kind of runtime metaprogramming that you do. This means that code which is perfectly valid without `@TypeChecked` will not compile anymore if you activate type checking. This is in particular true if you think of duck typing:

    class Duck {
        void quack() {              (1)
            println 'Quack!'
        }
    }
    class QuackingBird {
        void quack() {              (2)
            println 'Quack!'
        }
    }
    @groovy.transform.TypeChecked
    void accept(quacker) {
        quacker.quack()             (3)
    }
    accept(new Duck())              (4)

1 | we define a `Duck` class which defines a `quack` method
2 | we define another `QuackingBird` class which also defines a `quack` method
3 | `quacker` is loosely typed, so since the method is `@TypeChecked`, we will obtain a compile-time error
4 | even if in non type-checked Groovy, this would have passed

There are possible workarounds, like introducing an interface, but basically, by activating type checking, you gain type safety but you loose some features of the language. Hopefully, Groovy introduces some features like flow typing to reduce the gap between type-checked and non type-checked Groovy.

#### 6.2.5. Type inference

##### Principles

When code is annotated with `@TypeChecked`, the compiler performs type inference. It doesn’t simply rely on static types, but also uses various techniques to infer the types of variables, return types, literals, … so that the code remains as clean as possible even if you activate the type checker.

The simplest example is infering the type of a variable:

    def message = 'Welcome to Groovy!'              (1)
    println message.toUpperCase()                   (2)
    println message.upper() // compile time error   (3)

1 | a variable is declared using the `def` keyword
2 | calling `toUpperCase` is allowed by the type checker
3 | calling `upper` will fail at compile time

The reason the call to `toUpperCase` works is because the type of `message` was inferred as being a `String`.

##### Variables vs fields in type inference

It is worth noting that although the compiler performs type inference on local variables, it does not perform any kind of type inference on fields, always falling back to the declared type of a field. To illustrate this, let’s take a look at this example:

    class SomeClass {
        def someUntypedField                                                                (1)
        String someTypedField                                                               (2)

        void someMethod() {
            someUntypedField = '123'                                                        (3)
            someUntypedField = someUntypedField.toUpperCase()  // compile-time error        (4)
        }

        void someSafeMethod() {
            someTypedField = '123'                                                          (5)
            someTypedField = someTypedField.toUpperCase()                                   (6)
        }

        void someMethodUsingLocalVariable() {
            def localVariable = '123'                                                       (7)
            someUntypedField = localVariable.toUpperCase()                                  (8)
        }
    }

1 | `someUntypedField` uses `def` as a declaration type
2 | `someTypedField` uses `String` as a declaration type
3 | we can assign anything to `someUntypedField`
4 | yet calling `toUpperCase` fails at compile time because the field is not typed properly
5 | we can assign a `String` to a field of type `String`
6 | and this time `toUpperCase` is allowed
7 | if we assign a `String` to a local variable
8 | then calling `toUpperCase` is allowed on the local variable

Why such a difference? The reason is thread safety. At compile time, we can’t make any guarantee about the type of a field. Any thread can access any field at any time and between the moment a field is assigned a variable of some type in a method and the time is is used the line after, another thread may have changed the contents of the field. This is not the case for local variables: we know if they "escape" or not, so we can make sure that the type of a variable is constant (or not) over time. Note that even if a field is final, the JVM makes no guarantee about it, so the type checker doesn’t behave differently if a field is final or not.

| This is one of the reasons why we recommend to use typed fields. While using `def` for local variables is perfectly fine thanks to type inference, this is not the case for fields, which also belong to the public API of a class, hence the type is important.

##### Collection literal type inference

Groovy provides a syntax for various type literals. There are three native collection literals in Groovy:

- lists, using the `[]` literal

- maps, using the `[:]` literal

- ranges, using the `(..,..)` literal

The inferred type of a literal depends on the elements of the literal, as illustrated in the following table:

Literal | Inferred type
--- | ---
    def list = []
| `java.util.List`
    def list = ['foo','bar']
| `java.util.List<String>`
    def list = ["${foo}","${bar}"]
| `java.util.List<GString>` be careful, a `GString` is not a `String`!
    def map = [:]
| `java.util.LinkedHashMap`
    def map1 = [someKey: 'someValue']
    def map2 = ['someKey': 'someValue']
| `java.util.LinkedHashMap<String,String>`
    def map1 = [someKey: 'someValue']
    def map2 = ['someKey': 'someValue']
| `java.util.LinkedHashMap<GString,String>` be careful, the key is a `GString`!
    def intRange = (0..10)
| `groovy.lang.IntRange`
    def charRange = ('a'..'z')
| `groovy.lang.Range<String>` : uses the type of the bounds to infer the component type of the range

As you can see, with the noticeable exception of the `IntRange`, the inferred type makes use of generics types to describe the contents of a collection. In case the collection contains elements of different types, the type checker still performs type inference of the components, but uses the notion of least upper bound.

##### Least upper bound

In Groovy, the least upper bound of two types `A` and `B` is defined as a type which:

- superclass corresponds to the common super class of `A` and `B`

- interfaces correspond to the interfaces implemented by both `A` and `B`

- if `A` or `B` is a primitive type and that `A` isn’t equal to `B`, the least upper bound of `A` and `B` is the least upper bound of their wrapper types

If `A` and `B` only have one (1) interface in common and that their common superclass is `Object`, then the LUB of both is the common interface.

The least upper bound represents the minimal type to which both `A` and `B` can be assigned. So for example, if `A` and `B` are both `String`, then the LUB (least upper bound) of both is also `String`.

    class Top {}
    class Bottom1 extends Top {}
    class Bottom2 extends Top {}

    assert leastUpperBound(String, String) == String                    (1)
    assert leastUpperBound(ArrayList, LinkedList) == AbstractList       (2)
    assert leastUpperBound(ArrayList, List) == List                     (3)
    assert leastUpperBound(List, List) == List                          (4)
    assert leastUpperBound(Bottom1, Bottom2) == Top                     (5)
    assert leastUpperBound(List, Serializable) == Object                (6)

1 | the LUB of `String` and `String` is `String`
2 | the LUB of `ArrayList` and `LinkedList` is their common super type, `AbstractList`
3 | the LUB of `ArrayList` and `List` is their only common interface, `List`
4 | the LUB of two identical interfaces is the interface itself
5 | the LUB of `Bottom1` and `Bottom2` is their superclass `Top`
6 | the LUB of two types which have nothing in common is `Object`

In those examples, the LUB is always representable as a normal, JVM supported, type. But Groovy internally represents the LUB as a type which can be more complex, and that you wouldn’t be able to use to define a variable for example. To illustrate this, let’s continue with this example:

    interface Foo {}
    class Top {}
    class Bottom extends Top implements Serializable, Foo {}
    class SerializableFooImpl implements Serializable, Foo {}

What is the least upper bound of `Bottom` and `SerializableFooImpl`? They don’t have a common super class (apart from `Object`), but they do share 2 interfaces (`Serializable` and `Foo`), so their least upper bound is a type which represents the union of two interfaces (`Serializable` and `Foo`). This type cannot be defined in the source code, yet Groovy knows about it.

In the context of collection type inference (and generic type inference in general), this becomes handy, because the type of the components is inferred as the least upper bound. We can illustrate why this is important in the following example:

    interface Greeter { void greet() }                  (1)
    interface Salute { void salute() }                  (2)

    class A implements Greeter, Salute {                (3)
        void greet() { println "Hello, I'm A!" }
        void salute() { println "Bye from A!" }
    }
    class B implements Greeter, Salute {                (4)
        void greet() { println "Hello, I'm B!" }
        void salute() { println "Bye from B!" }
        void exit() { println 'No way!' }               (5)
    }
    def list = [new A(), new B()]                       (6)
    list.each {
        it.greet()                                      (7)
        it.salute()                                     (8)
        it.exit()                                       (9)
    }

1 | the `Greeter` interface defines a single method, `greet`
2 | the `Salute` interface defines a single method, `salute`
3 | class `A` implements both `Greeter` and `Salute` but there’s no explicit interface extending both
4 | same for `B`
5 | but `B` defines an additional `exit` method
6 | the type of `list` is inferred as "list of the LUB of `A` and `B`"
7 | so it is possible to call `greet` which is defined on both `A` and `B` through the `Greeter` interface
8 | and it is possible to call `salut` which is defined on both `A` and `B` through the `Salut` interface
9 | yet calling `exit` is a compile time error because it doesn’t belong to the LUB of `A` and `B` (only defined in `B`)

The error message will look like:

    [Static type checking] - Cannot find matching method Greeter or Salute#exit()

which indicates that the `exit` method is neither defines on `Greeter` nor `Salute`, which are the two interfaces defined in the least upper bound of `A` and `B`.

##### instanceof inference

In normal, non type checked, Groovy, you can write things like:

    class Greeter {
        String greeting() { 'Hello' }
    }

    void doSomething(def o) {
        if (o instanceof Greeter) {     (1)
            println o.greeting()        (2)
        }
    }

    doSomething(new Greeter())

1 | guard the method call with an `instanceof` check
2 | make the call

The method call works because of dynamic dispatch (the method is selected at runtime). The equivalent code in Java would require to cast `o` to a `Greeter` before calling the `greeting` method, because methods are selected at compile time:

    if (o instanceof Greeter) {
        System.out.println(((Greeter)o).greeting());
    }

However, in Groovy, even if you add `@TypeChecked` (and thus activate type checking) on the `doSomething` method, the cast is not necessary. The compiler embeds instanceof inference that makes the cast optional.

##### Flow typing

Flow typing is an important concept of Groovy in type checked mode and an extension of type inference. The idea is that the compiler is capable of infering the type of variables in the flow of the code, not just at initialization:

    @groovy.transform.TypeChecked
    void flowTyping() {
        def o = 'foo'                       (1)
        o = o.toUpperCase()                 (2)
        o = 9d                              (3)
        o = Math.sqrt(o)                    (4)
    }

1 | first, `o` is declared using `def` and assigned a `String`
2 | the compiler inferred that `o` is a `String`, so calling `toUpperCase` is allowed
3 | `o` is reassigned with a `double`
4 | calling `Math.sqrt` passes compilation because the compiler knows that at this point, `o` is a `double`

So the type checker is aware of the fact that the concrete type of a variable is different over time. In particular, if you replace the last assignment with:

    o = 9d
    o = o.toUpperCase()

The type checker will now fail at compile time, because it knows that `o` is a `double` when `toUpperCase` is called, so it’s a type error.

It is important to understand that it is not the fact of declaring a variable with `def` that triggers type inference. Flow typing works for any variable of any type. Declaring a variable with an explicit type only constraints what you can assign to a variable:

    @groovy.transform.TypeChecked
    void flowTypingWithExplicitType() {
        List list = ['a','b','c']           (1)
        list = list*.toUpperCase()          (2)
        list = 'foo'                        (3)
    }

1 | `list` is declared as an unchecked `List` and assigned a list literal of `String`s
2 | this line passes compilation because of flow typing: the type checker knows that `list` is at this point a `List<String>`
3 | but you can’t assign a `String` to a `List` so this is a type checking error

You can also note that even if the variable is declared without generics information, the type checker knows what is the component type. Therefore, such code would fail compilation:

    @groovy.transform.TypeChecked
    void flowTypingWithExplicitType() {
        List list = ['a','b','c']           (1)
        list.add(1)                         (2)
    }

1 | `list` is inferred as `List<String>`
2 | so adding an `int` to a `List<String>` is a compile-time error

Fixing this requires adding an explicit generic type to the declaration:

    @groovy.transform.TypeChecked
    void flowTypingWithExplicitType() {
        List<? extends Serializable> list = []                      (1)
        list.addAll(['a','b','c'])                                  (2)
        list.add(1)                                                 (3)
    }

1 | `list` declared as `List<? extends Serializable>` and initialized with an empty list
2 | elements added to the list conform to the declaration type of the list
3 | so adding an `int` to a `List<? extends Serializable>` is allowed

Flow typing has been introduced to reduce the difference in semantics between classic and static Groovy. In particular, consider the behavior of this code in Java:

    public Integer compute(String str) {
        return str.length();
    }
    public String compute(Object o) {
        return "Nope";
    }
    // ...
    Object string = "Some string";          (1)
    Object result = compute(string);        (2)
    System.out.println(result);             (3)

1 | `o` is declared as an `Object` and assigned a `String`
2 | we call the `compute` method with `o`
3 | and print the result

In Java, this code will output `0`, because method selection is done at compile time and based on the declared types. So even if `o` is a `String` at runtime, it is still the `Object` version which is called, because `o` has been declared as an `Object`. To be short, in Java, declared types are most important, be it variable types, parameter types or return types.

In Groovy, we could write:

    int compute(String string) { string.length() }
    String compute(Object o) { "Nope" }
    Object o = 'string'
    def result = compute(o)
    println result

But this time, it will return `6`, because the method which is chosen is chosen at runtime, based on the actual argument types. So at runtime, `o` is a `String` so the `String` variant is used. Note that this behavior has nothing to do with type checking, it’s the way Groovy works in general: dynamic dispatch.

In type checked Groovy, we want to make sure the type checker selects the same method at compile time, that the runtime would choose. It is not possible in general, due to the semantics of the language, but we can make things better with flow typing. With flow typing, `o` is inferred as a `String` when the `compute` method is called, so the version which takes a `String` and returns an `int` is chosen. This means that we can infer the return type of the method to be an `int`, and not a `String`. This is important for subsequent calls and type safety.

So in type checked Groovy, flow typing is a very important concept, which also implies that if `@TypeChecked` is applied, methods are selected based on the inferred types of the arguments, not on the declared types. This doesn’t ensure 100% type safety, because the type checker may select a wrong method, but it ensures the closest semantics to dynamic Groovy.

##### Advanced type inference

A combination of flow typing and least upper bound inference is used to perform advanced type inference and ensure type safety in multiple situations. In particular, program control structures are likely to alter the inferred type of a variable:

    class Top {
       void methodFromTop() {}
    }
    class Bottom extends Top {
       void methodFromBottom() {}
    }
    def o
    if (someCondition) {
        o = new Top()                               (1)
    } else {
        o = new Bottom()                            (2)
    }
    o.methodFromTop()                               (3)
    o.methodFromBottom()  // compilation error      (4)

1 | if `someCondition` is true, `o` is assigned a `Top`
2 | if `someCondition` is false, `o` is assigned a `Bottom`
3 | calling `methodFromTop` is safe
4 | but calling `methodFromBottom` is not, so it’s a compile time error

When the type checker visits an `if/else` control structure, it checks all variables which are assigned in `if/else` branches and computes the least upper bound of all assignments. This type is the type of the inferred variable after the `if/else` block, so in this example, `o` is assigned a `Top` in the `if` branch and a `Bottom` in the `else` branch. The LUB of those is a `Top`, so after the conditional branches, the compiler infers `o` as being a `Top`. Calling `methodFromTop` will therefore be allowed, but not `methodFromBottom`.

The same reasoning exists with closures and in particular closure shared variables. A closure shared variable is a variable which is defined outside of a closure, but used inside a closure, as in this example:

    def text = 'Hello, world!'                          (1)
    def closure = {
        println text                                    (2)
    }

1 | a variable named `text` is declared
2 | `text` is used from inside a closure. It is a closure shared variable.

Groovy allows developers to use those variables without requiring them to be final. This means that a closure shared variable can be reassigned inside a closure:

    String result
    doSomething { String it ->
        result = "Result: $it"
    }
    result = result?.toUpperCase()

The problem is that a closure is an independent block of code that can be executed (or not) at any time. In particular, `doSomething` may be asynchronous, for example. This means that the body of a closure doesn’t belong to the main control flow. For that reason, the type checker also computes, for each closure shared variable, the LUB of all assignments of the variable, and will use that `LUB` as the inferred type outside of the scope of the closure, like in this example:

    class Top {
       void methodFromTop() {}
    }
    class Bottom extends Top {
       void methodFromBottom() {}
    }
    def o = new Top()                               (1)
    Thread.start {
        o = new Bottom()                            (2)
    }
    o.methodFromTop()                               (3)
    o.methodFromBottom()  // compilation error      (4)

1 | a closure-shared variable is first assigned a `Top`
2 | inside the closure, it is assigned a `Bottom`
3 | `methodFromTop` is allowed
4 | `methodFromBottom` is a compilation error

Here, it is clear that when `methodFromBottom` is called, there’s no guarantee, at compile-time or runtime that the type of `o` will effectively be a `Bottom`. There are chances that it will be, but we can’t make sure, because it’s asynchronous. So the type checker will only allow calls on the least upper bound, which is here a `Top`.

#### 6.2.6. Closures and type inference

The type checker performs special inference on closures, resulting on additional checks on one side and improved fluency on the other side.

##### Return type inference

The first thing that the type checker is capable of doing is infering the return type of a closure. This is simply illustrated in the following example:

    @groovy.transform.TypeChecked
    int testClosureReturnTypeInference(String arg) {
        def cl = { "Arg: $arg" }                                (1)
        def val = cl()                                          (2)

        val.length()                                            (3)
    }

1 | a closure is defined, and it returns a string (more precisely a `GString`)
2 | we call the closure and assign the result to a variable
3 | the type checker inferred that the closure would return a string, so calling `length()` is allowed

As you can see, unlike a method which declares its return type explicitly, there’s no need to declare the return type of a closure: its type is inferred from the body of the closure.

Closures vs methods

It’s worth noting that return type inference is only applicable to closures. While the type checker could do the same on a method, it is in practice not desirable: in general, methods can be overriden and it is not statically possible to make sure that the method which is called is not an overriden version. So flow typing would actually think that a method returns something, while in reality, it could return something else, like illustrated in the following example:

    @TypeChecked
    class A {
        def compute() { 'some string' }             (1)
        def computeFully() {
            compute().toUpperCase()                 (2)
        }
    }
    @TypeChecked
    class B extends A {
        def compute() { 123 }                       (3)
    }

1 | class `A` defines a method `compute` which effectively returns a `String`
2 | this will fail compilation because the return type of `compute` is `def`(aka `Object`)
3 | class `B` extends `A` and redefines `compute`, this type returning an `int`

As you can see, if the type checker relied on the inferred return type of a method, with flow typing, the type checker could determine that it is ok to call `toUpperCase`. It is in fact an error, because a subclass can override `compute` and return a different object. Here, `B#compute` returns an `int`, so someone calling `computeFully` on an instance of `B` would see a runtime error. The compiler prevents this from happening by using the declared return type of methods instead of the inferred return type.

For consistency, this behavior is the same for every method, even if they are static or final.

##### Parameter type inference

In addition to the return type, it is possible for a closure to infer its parameter types from the context. There are two ways for the compiler to infer the parameter types:

- through implicit SAM type coercion

- through API metadata

To illustrate this, lets start with an example that will fail compilation due to the inability for the type checker to infer the parameter types:

    class Person {
        String name
        int age
    }

    void inviteIf(Person p, Closure<Boolean> predicate) {           (1)
        if (predicate.call(p)) {
            // send invite
            // ...
        }
    }

    @groovy.transform.TypeChecked
    void failCompilation() {
        Person p = new Person(name: 'Gerard', age: 55)
        inviteIf(p) {                                               (2)
            it.age >= 18 // No such property: age                   (3)
        }
    }

1 | the `inviteIf` method accepts a `Person` and a `Closure`
2 | we call it with a `Person` and a `Closure`
3 | yet `it` is not statically known as being a `Person` and compilation fails

In this example, the closure body contains `it.age`. With dynamic, not type checked code, this would work, because the type of `it` would be a `Person` at runtime. Unfortunately, at compile-time, there’s no way to know what is the type of `it`, just by reading the signature of `inviteIf`.

###### Explicit closure parameters

To be short, the type checker doesn’t have enough contextual information on the `inviteIf` method to determine statically the type of `it`. This means that the method call needs to be rewritten like this:

    inviteIf(p) { Person it ->                                  (1)
        it.age >= 18
    }

1 | the type of `it` needs to be declared explicitly

By explicitly declaring the type of the `it` variable, you can workaround the problem and make this code statically checked.

###### Parameters inferred from single-abstract method types

For an API or framework designer, there are two ways to make this more elegant for users, so that they don’t have to declare an explicit type for the closure parameters. The first one, and easiest, is to replace the closure with a SAM type:

    interface Predicate<On> { boolean apply(On e) }                 (1)

    void inviteIf(Person p, Predicate<Person> predicate) {          (2)
        if (predicate.apply(p)) {
            // send invite
            // ...
        }
    }

    @groovy.transform.TypeChecked
    void passesCompilation() {
        Person p = new Person(name: 'Gerard', age: 55)

        inviteIf(p) {                                               (3)
            it.age >= 18                                            (4)
        }
    }

1 | declare a `SAM` interface with an `apply` method
2 | `inviteIf` now uses a `Predicate<Person>` instead of a `Closure<Boolean>`
3 | there’s no need to declare the type of the `it` variable anymore
4 | `it.age` compiles properly, the type of `it` is inferred from the `Predicate#apply` method signature

| By using this technique, we leverage the automatic coercion of closures to SAM types feature of Groovy. The question whether you should use a SAM type or a Closure really depends on what you need to do. In a lot of cases, using a SAM interface is enough, especially if you consider functional interfaces as they are found in Java 8. However, closures provide features that are not accessible to functional interfaces. In particular, closures can have a delegate, and owner and can be manipulated as objects (for example, cloned, serialized, curried, …) before being called. They can also support multiple signatures (polymorphism). So if you need that kind of manipulation, it is preferable to switch to the most advanced type inference annotations which are described below.

The original issue that needs to be solved when it comes to closure parameter type inference, that is to say, statically determining the types of the arguments of a closure without having to have them explicitly declared, is that the Groovy type system inherits the Java type system, which is insufficient to describe the types of the arguments.

###### The `@ClosureParams` annotation

Groovy provides an annotation, `@ClosureParams` which is aimed at completing type information. This annotation is primarily aimed at framework and API developers who want to extend the capabilities of the type checker by providing type inference metadata. This is important if your library makes use of closures and that you want the maximum level of tooling support too.

Let’s illustrate this by fixing the original example, introducing the `@ClosureParams` annotation:

    import groovy.transform.stc.ClosureParams
    import groovy.transform.stc.FirstParam
    void inviteIf(Person p, @ClosureParams(FirstParam) Closure<Boolean> predicate) {        (1)
        if (predicate.call(p)) {
            // send invite
            // ...
        }
    }
    inviteIf(p) {                                                                       (2)
        it.age >= 18
    }

1 | the closure parameter is annotated with `@ClosureParams`
2 | it’s not necessary to use an explicit type for `it`, which is inferred

The `@ClosureParams` annotation minimally accepts one argument, which is named a type hint. A type hint is a class which is reponsible for completing type information at compile time for the closure. In this example, the type hint being used is `groovy.transform.stc.FirstParam` which indicated to the type checker that the closure will accept one parameter whose type is the type of the first parameter of the method. In this case, the first parameter of the method is `Person`, so it indicates to the type checker that the first parameter of the closure is in fact a `Person`.

The second argument is optional and named options. It’s semantics depends on the type hint class. Groovy comes with various bundled type hints, illustrated in the table below:

Table 2. Predefined type hints
Type hint | Polymorphic? | Description and examples
--- | --- | ---
`FirstParam` `SecondParam` `ThirdParam` | No | The first (resp. second, third) parameter type of the method
    import groovy.transform.stc.FirstParam
    void doSomething(String str, @ClosureParams(FirstParam) Closure c) {
        c(str)
    }
    doSomething('foo') { println it.toUpperCase() }
    import groovy.transform.stc.SecondParam
    void withHash(String str, int seed, @ClosureParams(SecondParam) Closure c) {
        c(31*str.hashCode()+seed)
    }
    withHash('foo', (int)System.currentTimeMillis()) {
        int mod = it%2
    }
    import groovy.transform.stc.ThirdParam
    String format(String prefix, String postfix, String o, @ClosureParams(ThirdParam) Closure c) {
        "$prefix${c(o)}$postfix"
    }
    assert format('foo', 'bar', 'baz') {
        it.toUpperCase()
    } == 'fooBAZbar'
`FirstParam.FirstGenericType` `SecondParam.FirstGenericType` `ThirdParam.FirstGenericType` | No | The first generic type of the first (resp. second, third) parameter of the method
    import groovy.transform.stc.FirstParam
    public <T> void doSomething(List<T> strings, @ClosureParams(FirstParam.FirstGenericType) Closure c) {
        strings.each {
            c(it)
        }
    }
    doSomething(['foo','bar']) { println it.toUpperCase() }
    doSomething([1,2,3]) { println(2*it) }
Variants for `SecondGenericType` and `ThirdGenericType` exist for all `FirstParam`, `SecondParam` and `ThirdParam` type hints.
`SimpleType` | No | A type hint for which the type of closure parameters comes from the options string.
    import groovy.transform.stc.SimpleType
    public void doSomething(@ClosureParams(value=SimpleType,options=['java.lang.String','int']) Closure c) {
        c('foo',3)
    }
    doSomething { str, len ->
        assert str.length() == len
    }
This type hint supports a single signature and each of the parameter is specified as a value of the options array using a fully-qualified type name or a primitive type.
`MapEntryOrKeyValue` | Yes | A dedicated type hint for closures that either work on a `Map.Entry` single parameter, or two parameters corresponding to the key and the value.
    import groovy.transform.stc.MapEntryOrKeyValue
    public <K,V> void doSomething(Map<K,V> map, @ClosureParams(MapEntryOrKeyValue) Closure c) {
        // ...
    }
    doSomething([a: 'A']) { k,v ->
        assert k.toUpperCase() == v.toUpperCase()
    }
    doSomething([abc: 3]) { e ->
        assert e.key.length() == e.value
    }
This type hint requires that the first argument is a `Map` type, and infers the closure parameter types from the map actual key/value types.
`FromAbstractTypeMethods` | Yes | Infers closure parameter types from the abstract method of some type. A signature is inferred for each abstract method.
    import groovy.transform.stc.FromAbstractTypeMethods
    abstract class Foo {
        abstract void firstSignature(int x, int y)
        abstract void secondSignature(String str)
    }
    void doSomething(@ClosureParams(value=FromAbstractTypeMethods, options=["Foo"]) Closure cl) {
        // ...
    }
    doSomething { a, b -> a+b }
    doSomething { s -> s.toUpperCase() }
If there are multiple signatures like in the example above, the type checker will only be able to infer the types of the arguments if the arity of each method is different. In the example above, `firstSignature` takes 2 arguments and `secondSignature` takes 1 argument, so the type checker can infer the argument types based on the number of arguments.
`FromString` | Yes | Infers the closure parameter typs from the `options` argument. The `options` argument consists of an array of comma-separated non-primitive types. Each element of the array corresponds to a single signature, and each comma in an element separate parameters of the signature. In short, this is the most generic type hint, and each string of the `options` map is parsed as if it was a signature literal. While being very powerful, this type hint must be avoided if you can because it increases the compilation times due to the necessity of parsing the type signatures. A single signature for a closure accepting a `String`:
    import groovy.transform.stc.FromString
    void doSomething(@ClosureParams(value=FromString, options=["String","String,Integer"]) Closure cl) {
        // ...
    }
    doSomething { s -> s.toUpperCase() }
    doSomething { s,i -> s.toUpperCase()*i }
A polymorphic closure, accepting either a `String` or a `String, Integer`:
    import groovy.transform.stc.FromString
    void doSomething(@ClosureParams(value=FromString, options=["String","String,Integer"]) Closure cl) {
        // ...
    }
    doSomething { s -> s.toUpperCase() }
    doSomething { s,i -> s.toUpperCase()*i }
A polymorphic closure, accepting either a `T` or a pair `T,T`:
    import groovy.transform.stc.FromString
    public <T> void doSomething(T e, @ClosureParams(value=FromString, options=["T","T,T"]) Closure cl) {
        // ...
    }
    doSomething('foo') { s -> s.toUpperCase() }
    doSomething('foo') { s1,s2 -> assert s1.toUpperCase() == s2.toUpperCase() }

| Even though you use `FirstParam`, `SecondParam` or `ThirdParam` as a type hint, it doesn’t stricly mean that the argument which will be passed to the closure will be the first (resp. second, third) argument of the method call. It only means that the type of the parameter of the closure will be the same as the type of the first (resp. second, third) argument of the method call.

In short, the lack of the `@ClosureParams` annotation on a method accepting a `Closure` will not fail compilation. If present (and it can be present in Java sources as well as Groovy sources), then the type checker has more information and can perform additional type inference. This makes this feature particularily interesting for framework developers.

##### `@DelegatesTo`

The `@DelegatesTo` annotation is used by the type checker to infer the type of the delegate. It allows the API designer to instruct the compiler what is the type of the delegate and the delegation strategy. The `@DelegatesTo` annotation is discussed in a specific section.

### 6.3. Static compilation (WIP)

#### 6.3.1. Dynamic vs static

In the type checking section, we have seen that Groovy provides optional type checking thanks to the `@TypeChecked` annotation. The type checker runs at compile time and performs a static analysis of dynamic code. The program will behave exactly the same whether type checking has been enabled or not. This means that the `@TypeChecked` annotation is neutral with regards to the semantics of a program. Even though it may be necessary to add type information in the sources so that the program is considered type safe, in the end, the semantics of the program are the same.

While this may sound fine, there is actually one issue with this: type checking of dynamic code, done at compile time, is by definition only correct if no runtime specific behavior occurs. For example, the following program passes type checking:

    class Computer {
        int compute(String str) {
            str.length()
        }
        String compute(int x) {
            String.valueOf(x)
        }
    }

    @groovy.transform.TypeChecked
    void test() {
        def computer = new Computer()
        computer.with {
            assert compute(compute('foobar')) =='6'
        }
    }

There are two `compute` methods. One accepts a `String` and returns an `int`, the other accepts an `int` and returns a `String`. If you compile this, it is considered type safe: the inner `compute('foobar')` call will return an `int`, and calling `compute` on this `int` will in turn return a `String`.

Now, before calling `test()`, consider adding the following line:

    Computer.metaClass.compute = { String str -> new Date() }

Using runtime metaprogramming, we’re actually modifying the behavior of the `compute(String)` method, so that instead of returning the length of the provided argument, it will return a `Date`. If you execute the program, it will fail at runtime. Since this line can be added from anywhere, in any thread, there’s absolutely no way for the type checker to statically make sure that no such thing happens. In short, the type checker is vulnerable to monkey patching. This is just one example, but this illustrates the concept that doing static analysis of a dynamic program is inherently wrong.

The Groovy language provides an alternative annotation to `@TypeChecked` which will actually make sure that the methods which are inferred as being called will effectively be called at runtime. This annotation turns the Groovy compiler into a static compiler, where all method calls are resolved at compile time and the generated bytecode makes sure that this happens: the annotation is `@groovy.transform.CompileStatic`.

#### 6.3.2. The `@CompileStatic` annotation

The `@CompileStatic` annotation can be added anywhere the `@TypeChecked` annotation can be used, that is to say on a class or a method. It is not necessary to add both `@TypeChecked` and `@CompileStatic`, as `@CompileStatic` performs everything `@TypeChecked` does, but in addition triggers static compilation.

Let’s take the example which failed, but this time let’s replace the `@TypeChecked` annotation with `@CompileStatic`:

    class Computer {
        int compute(String str) {
            str.length()
        }
        String compute(int x) {
            String.valueOf(x)
        }
    }

    @groovy.transform.CompileStatic
    void test() {
        def computer = new Computer()
        computer.with {
            assert compute(compute('foobar')) =='6'
        }
    }
    Computer.metaClass.compute = { String str -> new Date() }
    run()

This is the only difference. If we execute this program, this time, there is no runtime error. The `test` method became immune to monkey patching, because the `compute` methods which are called in its body are linked at compile time, so even if the metaclass of `Computer` changes, the program still behaves as expected by the type checker.

#### 6.3.3. Key benefits

There are several benefits of using `@CompileStatic` on your code:

- type safety

- immunity to monkey patching

- performance improvements

The performance improvements depend on the kind of program you are executing. It it is I/O bound, the difference between statically compiled code and dynamic code is barely noticeable. On highly CPU intensive code, since the bytecode which is generated is very close, if not equal, to the one that Java would produce for an equivalent program, the performance is greatly improved.

| Using the invokedynamic version of Groovy, which is accessible to people using JDK 7 and above, the performance of the dynamic code should be very close to the performance of statically compiled code. Sometimes, it can even be faster! There is only one way to determine which version you should choose: measuring. The reason is that depending on your program and the JVM that you use, the performance can be significantly different. In particular, the invokedynamic version of Groovy is very sensitive to the JVM version in use.