Session 7 : Subprograms
Introduction
- Two fundamental abstraction facilities
Process abstraction
- Emphasized from early days
- Discussed in this chapter
Data abstraction
- Emphasized in the1980s
- Discussed at length in Chapter 11
Fundamentals of Subprograms
- Each subprogram has a single entry point
- The calling program is suspended during execution of the called subprogram
- Control always returns to the caller when the called subprogram’s execution terminates
Local Referencing Environments
- Local variables can be stack-dynamic
Advantages
- Support for recursion
- Storage for locals is shared among some subprograms
Disadvantages
- Allocation/de-allocation, initialization time
- Indirect addressing
- Subprograms cannot be history sensitive
- Local variables can be static
Advantages and disadvantages are the opposite of those for stack-dynamic local variables
Implementing Parameter-Passing Methods
- In most languages parameter communication takes place thru the run-time stack
- Pass-by-reference are the simplest to implement; only an address is placed in the stack
Function header: void sub(int a, int b, int c, int d)
Function call in main: sub(w, x, y, z)
(pass w by value, x by result, y by value-result, z by reference
Parameters that are Subprogram Names
- It is sometimes convenient to pass subprogram names as parameters
- Issues:
- Are parameter types checked?
- What is the correct referencing environment for a subprogram that was sent as a parameter?
Calling Subprograms Indirectly
- Usually when there are several possible subprograms to be called and the correct one on a particular run of the program is not know until execution (e.g., event handling and GUIs)
- In C and C++, such calls are made through function pointers
- In C#, method pointers are implemented as objects called delegates
A delegate declaration:
public delegate int Change(int x);
This delegate type, named Change, can be instantiated with any method that takes an int parameter and returns an int value
A method: static int fun1(int x) { … }
Instantiate: Change chgfun1 = new Change(fun1);
Can be called with: chgfun1(12);
A delegate can store more than one address, which is called a multicast delegate
Overloaded Subprograms
- An overloaded subprogram is one that has the same name as another subprogram in the same referencing environment
Every version of an overloaded subprogram has a unique protocol
- C++, Java, C#, and Ada include predefined overloaded subprograms
- In Ada, the return type of an overloaded function can be used to disambiguate calls (thus two overloaded functions can have the same parameters)
- Ada, Java, C++, and C# allow users to write multiple versions of subprograms with the same name
User-Defined Overloaded Operators
- Operators can be overloaded in Ada, C++, Python, and Ruby
- A Python example
def __add__ (self, second) :
return Complex(self.real + second.real,
self.imag + second.imag)
Use: To compute x + y, x.__add__(y)
Closures
- A closure is a subprogram and the referencing environment where it was defined
- The referencing environment is needed if the subprogram can be called from any arbitrary place in the program
- A static-scoped language that does not permit nested subprograms doesn’t need closures
- Closures are only needed if a subprogram can access variables in nesting scopes and it can be called from anywhere
- To support closures, an implementation may need to provide unlimited extent to some variables (because a subprogram may access a nonlocal variable that is normally no longer alive)
Coroutines
- A coroutine is a subprogram that has multiple entries and controls them itself – supported directly in Lua
- Also called symmetric control: caller and called coroutines are on a more equal basis
- A coroutine call is named a resume
- The first resume of a coroutine is to its beginning, but subsequent calls enter at the point just after the last executed statement in the coroutine
- Coroutines repeatedly resume each other, possibly forever
- Coroutines provide quasi-concurrent execution of program units (the coroutines); their execution is interleaved, but not overlapped