Recursion, in mathematics and computer science, is a method of defining functions in which the function being defined is applied within its own definition; specifically it is defining an infinite statement using finite components. The term is also used more generally to describe a process of repeating objects in a selfsimilar way. For instance, when the surfaces of two mirrors are exactly parallel with each other the nested images that occur are a form of infinite recursion.
Contents 
In mathematics and computer science, a class of objects or methods exhibit recursive behavior when they can be defined by two properties:
For example, the following is a recursive definition of a person's ancestors:
The Fibonacci sequence is a classic example of recursion:
A convenient mental model of recursion defines the recursive object (whether that object is an equation, an algorithm, an image, or a rule) in terms of "previously defined" objects of the same class. For example: How do you move a stack of 100 boxes? Answer: you move one box, remember where you put it, and then solve the smaller problem: how do you move a stack of 99 boxes? Eventually, you're left with the problem of how to move a single box, which you know how to do.
Many mathematical axioms are based upon recursive rules. For example, the formal definition of the natural numbers in set theory follows: 0 is a natural number, and each natural number has a successor, which is also a natural number. By this base case and recursive rule, one can generate the set of all natural numbers
A more humorous illustration goes: "To understand recursion, one must first understand recursion." Or perhaps more accurate is the following, from Andrew Plotkin: "If you already know what recursion is, just remember the answer. Otherwise, find someone who is standing closer to Douglas Hofstadter than you are; then ask him or her what recursion is."
Recursively defined mathematical objects include functions, sets, and especially fractals.
The use of recursion in linguistics, and the use of recursion in general, dates back to the ancient Indian linguist Pāṇini in the 5th century BC, who made use of recursion in his grammar rules of Sanskrit.
Linguist Noam Chomsky theorizes that unlimited extension of a language such as English is possible only by the recursive device of embedding sentences in sentences. Thus, a chatty person may say, "Dorothy, who met the wicked Witch of the West in Munchkin Land where her wicked Witch sister was killed, liquidated her with a pail of water." Clearly, two simple sentences—"Dorothy met the Wicked Witch of the West in Munchkin Land" and "Her sister was killed in Munchkin Land"—can be embedded in a third sentence, "Dorothy liquidated her with a pail of water," to obtain a very verbose sentence.
However, if "Dorothy met the Wicked Witch" can be analyzed as a simple sentence, then the recursive sentence "She lived in the house Jack built" could be analyzed that way too, if "Jack built" is analyzed as an adjective, "Jackbuilt", that applies to the house in the same way "Wicked" applies to the Witch. "She lived in the Jackbuilt house" is unusual, perhaps poetic sounding, but it is not clearly wrong.
The idea that recursion is the essential property that enables language is challenged by linguist Daniel Everett in his work Cultural Constraints on Grammar and Cognition in Pirahã: Another Look at the Design Features of Human Language in which he hypothesizes that cultural factors made recursion unnecessary in the development of the Pirahã language. This concept challenges Chomsky's idea that recursion is the only trait which differentiates human and animal communication and is currently under intense debate.
Recursion in linguistics enables 'discrete infinity' by embedding phrases within phrases of the same type in a hierarchical structure. Without recursion, language does not have 'discrete infinity' and cannot embed sentences into infinity (with a 'Russian doll' effect). Everett contests that language must have discrete infinity, and that the Pirahã language  which he claims lacks recursion  is in fact finite. He likens it to the finite game of chess, which has a finite number of moves but is nevertheless very productive, with novel moves being discovered throughout history.
Recursion is the process a procedure goes through when one of the steps of the procedure involves rerunning the procedure. A procedure that goes through recursion is said to be recursive. Something is also said to be recursive when it is the result of a recursive procedure.
To understand recursion, one must recognize the distinction between a procedure and the running of a procedure. A procedure is a set of steps that are to be taken based on a set of rules. The running of a procedure involves actually following the rules and performing the steps. An analogy might be that a procedure is like a menu in that it is the possible steps, while running a procedure is actually choosing the courses for the meal from the menu.
A procedure is recursive if one of the steps that makes up the procedure calls for a new running of the procedure. Therefore, a recursive fourcourse meal would be a meal in which one of the choices of appetizer, salad, entrée, or dessert was an entire meal unto itself. So a recursive meal might be potato skins, baby greens salad, chicken Parmesan, and for dessert, a fourcourse meal, consisting of crab cakes, Caesar salad, for an entrée, a fourcourse meal, and chocolate cake for dessert, so on until each of the meals within the meals is completed.
A recursive procedure must complete every one of its steps. Even if a new running is called in one of its steps, each running must run through the remaining steps. What this means is that even if the salad is an entire fourcourse meal unto itself, you still have to eat your entrée and dessert.
A common joke (for example recursion in the Jargon File) is the following "definition" of recursion.
(Obviously, this recursion lacks the base case, so it will recur indefinitely.)
This is a parody on references in dictionaries, which in some cases may lead to circular definitions among related words. Jokes often have an element of wisdom, and also an element of misunderstanding. This one is also the shortest possible example of an erroneous recursive definition of an object, the error being the absence of the termination condition (or lack of the initial state, if looked at from an opposite point of view). Newcomers to recursion are often bewildered by its apparent circularity, until they learn to appreciate that a termination condition is key.
An example of this can be found by searching Google for the term "Recursion". Google cleverly puts the searcher in an endless cycle, of suggesting "Recursion" as the word they were trying to spell, even though that's exactly the input they just used.
A variation is:
which actually does terminate, as soon as the reader "gets it."
Another example occurs in Kernighan and Ritchie's "The C Programming Language." The following index entry is found on page 269:
Other examples are recursive acronyms, such as GNU, PHP, YAML or HURD.
Some subtle jokes in mathematical recursive definitions include:
fact(∞) > ∞ fact(N) > fact(N+1)/(N+1)
fib(∞) > ∞ fib(N) > fib(N+2)  fib(N+1)
The canonical example of a recursively defined set is given by the natural numbers:
(The doubt with this definition is that we assume: 1.we understand the "+" operation and 2.n + 1 is not in current . These two assumptions mean that before we understand the natural numbers, we already know the "+" operation on them.)
Another interesting example is the set of all true "reachable" propositions in an axiomatic system.
This set is called 'true reachable propositions' because: in nonconstructive approaches to the foundations of mathematics, the set of true propositions is larger than the set recursively constructed from the axioms and rules of inference. See also Gödel's incompleteness theorems.
(Note that determining whether a certain object is in a recursively defined set is not an algorithmic task.)
A function may be partly defined in terms of itself. A familiar example is the Fibonacci number sequence: F(n) = F(n − 1) + F(n − 2). For such a definition to be useful, it must lead to values which are nonrecursively defined, in this case F(0) = 0 and F(1) = 1.
A famous recursive function is the Ackermann function which, unlike the Fibonacci sequence, cannot be expressed without recursion.
Applying the standard technique of proof by cases to recursivelydefined sets or functions as in the preceding sections yields structural induction, a powerful generalization of mathematical induction which is widely used to derive proofs in mathematical logic and computer science.
For instance, the standard way to define new systems of mathematics or logic is to define objects (such as "true" and "false", or "all natural numbers"), then define operations on these. These are the base cases. After this, all valid computations in the system are defined with rules for assembling these. In this way, if the base cases and rules are all proven to be calculable, then any formula in the mathematical system will also be calculable.
While the above example may seem unexciting, this type of proof is the normal way to prove that a calculation is impossible. This can often save a lot of time. For example, this type of proof was used to prove that the area of a circle is not a simple ratio of its diameter, and that no angle can be trisected with compass and straightedge—both puzzles that fascinated the ancients.
Dynamic programming is an approach to optimization which restates a multiperiod or multistep optimization problem in recursive form. The key result in dynamic programming is the Bellman equation, which writes the value of the optimization problem at an earlier time (or earlier step) in terms of its value at a later time (or later step).
A common method of simplification is to divide a problem into subproblems of the same type. As a computer programming technique, this is called divide and conquer and is key to the design of many important algorithms. Divide and conquer serves as a topdown approach to problem solving, where problems are solved by solving smaller and smaller instances. A contrary approach is dynamic programming. This approach serves as a bottomup approach, where problems are solved by solving larger and larger instances, until the desired size is reached.
A classic example of recursion is the definition of the factorial function, given here in C code:
unsigned int factorial(unsigned int n) { if (n <= 1) { return 1; } else { return n * factorial(n1); } }
The function calls itself recursively on a smaller version of the input (n  1) and multiplies the result of the recursive call by n, until reaching the base case, analogously to the mathematical definition of factorial.
Recursion in computer programming is exemplified when a function is defined in terms of simpler, often smaller versions of itself. The solution to the problem is then devised by combining the solutions obtained from the simpler versions of the problem. One example application of recursion is in parsers for programming languages. The great advantage of recursion is that an infinite set of possible sentences, designs or other data can be defined, parsed or produced by a finite computer program.
Recurrence relations are equations to define one or more sequences recursively. Some specific kinds of recurrence relation can be "solved" to obtain a nonrecursive definition.
Use of recursion in an algorithm has both advantages and disadvantages. The main advantage is usually simplicity. The main disadvantage is often that the algorithm may require large amounts of memory if the depth of the recursion is very large.
In set theory, this is a theorem guaranteeing that recursively defined functions exist. Given a set X, an element a of X and a function , the theorem states that there is a unique function (where N denotes the set of natural numbers including zero) such that
for any natural number n.
Take two functions F and G of domain N and codomain A such that:
where a is an element of A. We want to prove that F = G. Two functions are equal if they:
Some common recurrence relations are:


F# : Recursion and Recursive Functions 
A recursive function is a function which calls itself.
Interestingly, in contrast to many other languages, functions in F#
are not recursive by default. A programmer needs to explicitly mark
a function as recursive using the rec
keyword:
let rec someFunction = ...
Contents 
The factorial of a nonnegative integer n, denoted by n!, is the product of all positive integers less than or equal to n. For example, 6! = 6 * 5 * 4 * 3 * 2 * 1 = 720.
In mathematics, the factorial is defined as follows:
Naturally, we'd calculate a factorial by hand using the following:
fact(6) = = 6 * fact(6  1) = 6 * 5 * fact(5  1) = 6 * 5 * 4 * fact(4  1) = 6 * 5 * 4 * 3 * fact(3  1) = 6 * 5 * 4 * 3 * 2 * fact(2  1) = 6 * 5 * 4 * 3 * 2 * 1 * fact(1  1) = 6 * 5 * 4 * 3 * 2 * 1 * 1 = 720
In F#, the factorial function can be written concisely as follows:
let rec fact x = if x < 1 then 1 else x * fact (x  1)
Here's a complete program:
open System let rec fact x = if x < 1 then 1 else x * fact (x  1) (* // can also be written using pattern matching syntax: let rec fact = function  0  1 > 1  n > n * fact (n  1) *) Console.WriteLine(fact 6)
The greatest common divisor, or GCD function, calculates the largest integer number which evenly divides two other integers. For example, largest number that evenly divides 259 and 111 is 37, denoted GCD(259, 111) = 37.
Euclid discovered a remarkably simple recursive algorithm for calculating the GCD of two numbers:
To calculate this by hand, we'd write:
gcd(259, 111) = gcd(111, 259 % 111) = gcd(111, 37) = gcd(37, 0) = 37
In F#, we can use the %
(modulus) operator to
calculate the remainder of two numbers, so naturally we can define
the GCD function in F# as follows:
open System let rec gcd x y = if y = 0 then x else gcd y (x % y) Console.WriteLine(gcd 259 111) // prints 37
Let's say we have a function A
which, at some
point, calls function B
. When B
finishes
executing, the CPU must continue executing A
from the
point where it left off. To "remember" where to return, the
function A
passes a return address as an
extra argument to B
on the stack; B
jumps
back to the return address when it finishes executing. This means
calling a function, even one that doesn't take any parameters,
consumes stack space, and its extremely easy for a recursive
function to consume all of the available memory on the stack.
A tail recursive function is a special case of recursion in which the last instruction executed in the method is the recursive call. F# and many other functional languages can optimize tail recursive functions; since no extra work is performed after the recursive call, there is no need for the function to remember where it came from, and hence no reason to allocate additional memory on the stack.
F# optimizes tailrecursive functions by telling the CLR to drop the current stack frame before executing the target function. As a result, tailrecursive functions can recurse indefinitely without consuming stack space.
Here's nontail recursive function:
> let rec count n = if n = 1000000 then printfn "done" else if n % 1000 = 0 then printfn "n: %i" n count (n + 1) (* recursive call *) () (* < This function is not tail recursive because it performs extra work (by returning unit) after the recursive call is invoked. *);; val count : int > unit > count 0;; n: 0 n: 1000 n: 2000 n: 3000 ... n: 58000 n: 59000 Session termination detected. Press Enter to restart. Process is terminated due to StackOverflowException.
Let's see what happens if we make the function properly tailrecursive:
> let rec count n = if n = 1000000 then printfn "done" else if n % 1000 = 0 then printfn "n: %i" n count (n + 1) (* recursive call *);; val count : int > unit > count 0;; n: 0 n: 1000 n: 2000 n: 3000 n: 4000 ... n: 995000 n: 996000 n: 997000 n: 998000 n: 999000 done
If there was no check for n = 1000000
, the function
would run indefinitely. Its important to ensure that all recursive
function have a base case to ensure they terminate
eventually.
Let's imagine that, for our own amusement, we wanted to
implement a multiplication function in terms of the more
fundamental function of addition. For example, we know that 6
* 4
is the same as 6 + 6 + 6 + 6
, or more
generally we can define multiplication recursively as M(a, b)
= a + M(a, b  1), b > 1
. In F#, we'd write this function
as:
let rec slowMultiply a b = if b > 1 then a + slowMultiply a (b  1) else a
It may not be immediately obvious, but this function is not tail recursive. It might be more obvious if we rewrote the function as follows:
let rec slowMultiply a b = if b > 1 then let intermediate = slowMultiply a (b  1) (* recursion *) let result = a + intermediate (* < additional operations *) result else a
Since the slowMultiply
function isn't tail
recursive, it throws a StackOverFlowException
for
inputs which result in very deep recursion:
> let rec slowMultiply a b = if b > 1 then a + slowMultiply a (b  1) else a;; val slowMultiply : int > int > int > slowMultiply 3 9;; val it : int = 27 > slowMultiply 2 14;; val it : int = 28 > slowMultiply 1 100000;; Process is terminated due to StackOverflowException. Session termination detected. Press Enter to restart.
Its possible to rewrite most recursive functions into their tailrecursive forms using an accumulating parameter:
> let slowMultiply a b = let rec loop acc counter = if counter > 1 then loop (acc + a) (counter  1) (* tail recursive *) else acc loop a b;; val slowMultiply : int > int > int > slowMultiply 3 9;; val it : int = 27 > slowMultiply 2 14;; val it : int = 28 > slowMultiply 1 100000;; val it : int = 100000
The accumulator parameter in the inner loop holds the state our function throughout each recursive iteration.
The following function calculates the nth number in the Fibonacci sequence:
let rec fib = function  0I > 0I  1I > 1I  n > fib(n  1I) + fib(n  2I)
val fib : bigint > bigint
. Previously, we've
been using the int
or System.Int32
type
to represent numbers, but this type has a maximum value of
2,147,483,647
. The type bigint
is used
for arbitrary size integers such as integers with billions
of digits. The maximum value of bigint
is constrained
only by the available memory on a users machine, but for most
practical computing purposes we can say this type is
boundless.The function above is neither tailrecursive nor particularly efficient with a computational complexity O(2^{n}). The tailrecursive form of this function has a computational complexity of O(n). Rewrite the function above so that its tail recursive.
You can verify the correctness of your function using the following:
fib(0) = 0 fib(1) = 1 fib(2) = 1 fib(3) = 2 fib(4) = 3 fib(5) = 5 fib(10) = 55 fib(100) = 354224848179261915075
[[File:thumbrightA visual form of recursion is the Droste effect. It leads to selfsimilar images.]] Recursion is a word from mathematics. In mathematics and in computer science, it is used to define a thing, usually a function. Unlike with normal definitions, the function to be defined can be used to define itself.
Recursion consists of two steps:
An example might be how to define ancestor, using recursion:
For the real explanation see Recursion.
