Package groovy.transform
Annotation Type 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