1.55k likes | 1.7k Views
The joys of recursion. Programming Fundamentals 22 Feliks Klu ź niak. Most modern programming languages have very similar runtime models. The memory occupied by a TL program is organized like this:. Code. The stack. Free space. The heap.
E N D
The joys of recursion Programming Fundamentals 22 Feliks Kluźniak TL: The joys of recursion
Most modern programming languages have very similar runtime models. The memory occupied by a TL program is organized like this: Code The stack Free space The heap TL: The joys of recursion
Most modern programming languages have very similar runtime models. The memory occupied by a TL program is organized like this: The program, translated to machine code Code The stack Free space The heap TL: The joys of recursion
Most modern programming languages have very similar runtime models. The memory occupied by a TL program is organized like this: The program, translated to machine code Code The recursion stack(*) (we will talk about this in a minute) (*) a.k.a. the execution stack The stack Free space The heap TL: The joys of recursion
Most modern programming languages have very similar runtime models. The memory occupied by a TL program is organized like this: The program, translated to machine code Code The recursion stack (we will talk about this in a minute) The stack Free space Storage for long-lived objects (we will talk about this in a few weeks) The heap TL: The joys of recursion
Most modern programming languages have very similar runtime models. The memory occupied by a TL program is organized like this: The program, translated to machine code Code The recursion stack (we will talk about this in a minute) The stack Free storage: room for the stack or the heap to grow Free space Storage for long-lived objects (we will talk about this in a few weeks) The heap TL: The joys of recursion
A stack is a data structure that behaves somewhat like a stack of plates. TL: The joys of recursion
A stack is a data structure that behaves somewhat like a stack of plates. You can push a couple of plates onto the stack…. TL: The joys of recursion
A stack is a data structure that behaves somewhat like a stack of plates. You can push a couple of plates onto the stack…. TL: The joys of recursion
A stack is a data structure that behaves somewhat like a stack of plates. You can push a couple of plates onto the stack, then push again… TL: The joys of recursion
A stack is a data structure that behaves somewhat like a stack of plates. You can push a couple of plates onto the stack, then push again… TL: The joys of recursion
A stack is a data structure that behaves somewhat like a stack of plates. You can push a couple of plates onto the stack, then push again, then maybe pop a few … TL: The joys of recursion
A stack is a data structure that behaves somewhat like a stack of plates. You can push a couple of plates onto the stack, then push again, then maybe pop a few … TL: The joys of recursion
A stack is a data structure that behaves somewhat like a stack of plates. You can push a couple of plates onto the stack, then push again, then maybe pop a few, push again… TL: The joys of recursion
A stack is a data structure that behaves somewhat like a stack of plates. You can push a couple of plates onto the stack, then push again, then maybe pop a few, push again… TL: The joys of recursion
A stack is a data structure that behaves somewhat like a stack of plates. You can push a couple of plates onto the stack, then push again, then maybe pop a few, push again and pop again… TL: The joys of recursion
A stack is a data structure that behaves somewhat like a stack of plates. You can push a couple of plates onto the stack, then push again, then maybe pop a few, push again and pop again… TL: The joys of recursion
A stack is a data structure that behaves somewhat like a stack of plates. You can push a couple of plates onto the stack, then push again, then maybe pop a few, push again and pop again, but you don’t remove/insert plates from/to the middle of the stack. TL: The joys of recursion
This behaviour is simulated by storing items in memory. A special variable indicates the top of the stack. item 1 item 2 item 3 item 4 We normally show the stack growing downwards, because we tend to show low addresses at the top of a drawing. u n u s e d TL: The joys of recursion
This behaviour is simulated by storing items in memory. A special variable indicates the top of the stack. We push by adding stuff to free memory and modifying the index of the top… item 1 item 2 item 3 item 4 We normally show the stack growing downwards, because we tend to show low addresses at the top of a drawing. u n u s e d TL: The joys of recursion
This behaviour is simulated by storing items in memory. A special variable indicates the top of the stack. We push by adding stuff to free memory and modifying the index of the top… item 1 item 2 item 3 item 4 item 5 We normally show the stack growing downwards, because we tend to show low addresses at the top of a drawing. u n u s e d TL: The joys of recursion
This behaviour is simulated by storing items in memory. A special variable indicates the top of the stack. We push by adding stuff to free memory and modifying the index of the top, and pop simply by modifying the index of the top. item 1 item 2 item 3 item 4 item 5 We normally show the stack growing downwards, because we tend to show low addresses at the top of a drawing. u n u s e d TL: The joys of recursion
This behaviour is simulated by storing items in memory. A special variable indicates the top of the stack. We push by adding stuff to free memory and modifying the index of the top, and pop simply by modifying the index of the top. item 1 item 2 item 3 item 4 item 5 We normally show the stack growing downwards, because we tend to show low addresses at the top of a drawing. u n u s e d TL: The joys of recursion
This behaviour is simulated by storing items in memory. A special variable indicates the top of the stack. We push by adding stuff to free memory and modifying the index of the top, and pop simply by modifying the index of the top. item 1 item 2 item 3 item 4 item 5 We normally show the stack growing downwards, because we tend to show low addresses at the top of a drawing. u n u s e d TL: The joys of recursion
Most modern programming languages have very similar runtime models. The memory occupied by a TL program is organized like this: The program, translated to machine code Code The recursion stack (we will talk about this in a minute) The stack Free storage: room for the stack or the heap to grow Free space Storage for long-lived objects (we will talk about this in a few weeks) The heap TL: The joys of recursion
When a procedure or function is invoked, an activation record (a.k.a. an environment frame) is pushed onto the recursion stack. A special variable (or register) CF shows the address of the topmost frame. v space for arguments address of previous frame CF the trace (where to return) space for local variables TL: The joys of recursion
When a procedure or function is invoked, an activation record (a.k.a. an environment frame) is pushed onto the recursion stack. A special variable (or register) CF shows the address of the topmost frame. CFstands for Current Frame . v space for arguments address of previous frame CF the trace (where to return) space for local variables TL: The joys of recursion
When a procedure or function is invoked, an activation record (a.k.a. an environment frame) is pushed onto the recursion stack. A special variable (or register) CF shows the address of the topmost frame. CFstands for Current Frame . Since the total size of the local variables of a subroutine is known, so is the address of the first free word above the topmost frame on the stack. v space for arguments address of previous frame CF the trace (where to return) space for local variables TL: The joys of recursion
When a procedure or function is invoked, an activation record (a.k.a. an environment frame) is pushed onto the recursion stack. A special variable (or register) CF shows the address of the topmost frame. CFstands for Current Frame . Since the total size of the local variables of a subroutine is known, so is the address of the first free word above the topmost frame on the stack. The address of the previous frame is commonly called a “link” (more precisely: a “dynamic link”). v space for arguments address of previous frame CF the trace (where to return) space for local variables TL: The joys of recursion
When a procedure or function is invoked, an activation record (a.k.a. an environment frame) is pushed onto the recursion stack: arguments and local variables are always addressed as CF + some offset. v space for arguments address of previous frame CF the trace (where to return) space for local variables TL: The joys of recursion
When a procedure or function is invoked, an activation record (a.k.a. an environment frame) is pushed onto the recursion stack: arguments and local variables are always addressed as CF + some offset. v space for arguments For example, the address of a local variable v might be CF + 7. address of previous frame CF the trace (where to return) space for local variables TL: The joys of recursion
When a procedure or function is invoked, an activation record (a.k.a. an environment frame) is pushed onto the recursion stack: all arguments and local variables are always addressed as CF + some offset. v space for arguments For example, the address of a local variable v might be CF + 7. The offset 7 would always be the same, but the value of CF would change from invocation to invocation. address of previous frame CF the trace (where to return) space for local variables TL: The joys of recursion
This means that the local variables of a procedure do not have fixed addresses, and that they exist only from the time a subroutine is invoked to the time it returns. v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
This means that the local variables of a procedure do not have fixed addresses, and that they exist only from the time a subroutine is invoked to the time it returns. So our previous observations about the state space must be modified accordingly. v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
This means that the local variables of a procedure do not have fixed addresses, and that they exist only from the time a subroutine is invoked to the time it returns. It also means that we can have several invocations of the same subroutine existing at the same time! Each of these invocations has a different activation record, but they all share the same code. v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
This means that the local variables of a procedure do not have fixed addresses, and that they exist only from the time a subroutine is invoked to the time it returns. It also means that we can have several invocations of the same subroutine existing at the same time! Each of these invocations has a different activation record, but they all share the same code. In other words, subroutines can be recursive. v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
A subroutine S is directly recursive if it contains an invocation of S (i.e., of itself). v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
A subroutine S is directly recursive if it contains an invocation of S (i.e., of itself). S is indirectly recursive if it contains an invocation of some other subroutine S2, and S2 invokes S … v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
A subroutine S is directly recursive if it contains an invocation of S (i.e., of itself). S is indirectly recursive if it contains an invocation of some other subroutine S2, and S2 invokes S, or invokes a subroutine S3 that invokes S, or … etc. v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
Let us look at an example of a directly recursive subroutine. v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
Let us look at an example of a directly recursive subroutine. The mathematical function “factorial of N”, written as N ! , is defined as follows (for N >= 0 ) : N ! = 1 if N = 0 N ! = ( N – 1 ) ! * N if N > 0 v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
Let us look at an example of a directly recursive subroutine. The mathematical function “factorial of N”, written as N ! , is defined as follows (for N >= 0 ) : N ! = 1 if N = 0 N ! = ( N – 1 ) ! * N if N > 0 For example, 0 ! = ? v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
Let us look at an example of a directly recursive subroutine. The mathematical function “factorial of N”, written as N ! , is defined as follows (for N >= 0 ) : N ! = 1 if N = 0 N ! = ( N – 1 ) ! * N if N > 0 For example, 0 ! = 1 v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
Let us look at an example of a directly recursive subroutine. The mathematical function “factorial of N”, written as N ! , is defined as follows (for N >= 0 ) : N ! = 1 if N = 0 N ! = ( N – 1 ) ! * N if N > 0 For example, 0 ! = 1 1 ! = ? v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
Let us look at an example of a directly recursive subroutine. The mathematical function “factorial of N”, written as N ! , is defined as follows (for N >= 0 ) : N ! = 1 if N = 0 N ! = ( N – 1 ) ! * N if N > 0 For example, 0 ! = 1 1 ! = 1 * 1 = 1 2 ! = ? v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
Let us look at an example of a directly recursive subroutine. The mathematical function “factorial of N”, written as N ! , is defined as follows (for N >= 0 ) : N ! = 1 if N = 0 N ! = ( N – 1 ) ! * N if N > 0 For example, 0 ! = 1 1 ! = 1 * 1 = 1 2 ! = 1! * 2 = 2 3 ! = ? v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
Let us look at an example of a directly recursive subroutine. The mathematical function “factorial of N”, written as N ! , is defined as follows (for N >= 0 ) : N ! = 1 if N = 0 N ! = ( N – 1 ) ! * N if N > 0 For example, 0 ! = 1 1 ! = 1 * 1 = 1 2 ! = 1! * 2 = 2 3 ! = 2! * 3 = ? v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
Let us look at an example of a directly recursive subroutine. The mathematical function “factorial of N”, written as N ! , is defined as follows (for N >= 0 ) : N ! = 1 if N = 0 N ! = ( N – 1 ) ! * N if N > 0 For example, 0 ! = 1 1 ! = 1 * 1 = 1 2 ! = 1! * 2 = 2 3 ! = 2! * 3 = 6 This type of definition is called recursive: it defines a function in terms of itself. v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
Let us look at an example of a directly recursive subroutine. The mathematical function “factorial of N”, written as N ! , is defined as follows (for N >= 0 ) : N ! = 1 if N = 0 the base case N ! = ( N – 1 ) ! * N if N > 0 For example, 0 ! = 1 1 ! = 1 * 1 = 1 2 ! = 1! * 2 = 2 3 ! = 2! * 3 = 6 This type of definition is called recursive: it defines a function in terms of itself. The definition Is not circular, because there is a base case. v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion
N ! = 1 if N = 0 N ! = ( N – 1 ) ! * N if N > 0 In TL, we can write this as follows: func factorial ( n : int ) : int begin var value : int; assert( n >= 0 ); if n = 0 then value := 1 else value := factorial( n – 1 ) * n fi; return value end v space for arguments address of previous frame the trace (where to return) space for local variables TL: The joys of recursion