Tail recursionTail recursion\ is a method for partially transforming a recursion in a program into an iteration: it applies when the recursive calls in a function are the last executed statements in that function. Tail recursion is used in functional programming languages to fit an iterative process into a recursive function. Functional programming languages can typically detect tail recursion and optimize the execution into an iteration which saves stack space, as described below. Since having a complete call graph is a daunting task for compilers, a mere tail call is usually referred to as being tail recursive. Besides space and execution efficiency, the tail recursion is important to allowing a common idiom in functional programming, continuation-passing style (CPS) without quickly running out of stack space. Since the tail recursion is so important in this portability of code, the standard for Scheme programming language requires implementations to be properly tail recursive. This means that programmers can expect the tail recursive code to be interpreted as efficiently as stack-based iterative code. The tail expression in Scheme is defined as follows:
(define (factorial n)\n (define (iterate n acc)\n (if (<= n 1)\n acc\n (iterate (- n 1) (* acc n))))\n (iterate n 1))As you can see, the inner procedure iterate calls itself last in the control flow. This allows an interpreter or compiler to reorganize the execution which would ordinarily look like this:
call factorial (3)\n call iterate (3 1)\n call iterate (2 3)\n call iterate (1 6)\n return 6\n return 6\n return 6\n return 6into the more space- (and time-) efficient variant: call factorial (3)\n replace arguments with (3 1), jump into "iterate"\n replace arguments with (2 3), re-iterate\n replace arguments with (1 6), re-iterate\n return 6This reorganization saves space because no state except for the calling function's address needs to be saved, neither on the stack nor on the heap. This also means that the programmer need not worry about running out of stack or heap space for extremely deep recursions. Some programmers working in functional languages will rewrite recursive code to be tail recursive so they can take advantage of this feature.\nThis often requires addition of an "accumulator" ( acc in the above implementation of factorial) as an argument to a function.\nIn some cases (such as filtering lists) and in some languages, full tail recursion may require a function that was previously purely functional to be written such that it mutates references stored in other variables.
See also tail recursion modulo cons.
|
||
"Happiness is good health and a bad memory." - Ingrid Bergman (1917-1982) |
