TailRecursive (Groovy 5.0.7)

Package: groovy.transform

## [Java] Annotation Type TailRecursive

- groovy.transform.TailRecursive

-     @Retention(RetentionPolicy.SOURCE)
      @Target(ElementType.METHOD)
      @GroovyASTTransformationClass({"org.codehaus.groovy.transform.tailrec.TailRecursiveASTTransformation"})
      public @interface TailRecursive

  Method annotation used to transform methods with tail recursive calls into iterative methods automagically since the JVM cannot do this itself. This works for both static and non-static methods.

  It allows you to write a method like this:

       import groovy.transform.TailRecursive
       class Target {
            @TailRecursive
            long sumUp(long number, long sum = 0) {
                if (number == 0)
                    return sum;
                sumUp(number - 1, sum + number)
            }
       }
       def target = new Target()
       assert target.sumUp(100) == 5050
       assert target.sumUp(1000000) == 500000500000 //will blow the stack on most machines when used without @TailRecursive

  `@TailRecursive` is supposed to work in combination with `@CompileStatic`

  Known shortcomings:

  - Only non-void methods are currently being handled. Void methods will fail compilation.
  - Only direct recursion (calling the exact same method again) is supported.
  - Mixing of tail calls and non-tail calls is not possible. The compiler will complain if some recursive calls cannot be handled.
  - Checking if a recursive call is really tail-recursive is not very strict. You might run into cases where non-tail calls will be considered tail calls.
  - In the presence of method overloading and method overriding you might run into situations where a call is considered recursive although it really is not.
  - Catching `Throwable` around a recursive might lead to problems
  - Non trivial continuation passing style examples do not work.
  - Probably many unrecognized edge cases.

  More examples:

       import groovy.transform.TailRecursive

       @TailRecursive
       long sizeOfList(list, counter = 0) {
           if (list.size() == 0) {
               counter
           } else {
              sizeOfList(list.tail(), counter + 1)
           }
       }

       // Without @TailRecursive a StackOverFlowError
       // is thrown.
       assert sizeOfList(1..10000) == 10000

  Since:
    2.3

- - ### Inherited Methods Summary

    Inherited Methods
    Methods inherited from class | Name
    --- | ---
    `class Object` | `equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`