![]() Capt. Horatio T.P. Webb |
Functions and Subroutines |
There are three potential structures that organize the instructions in a program: main, subroutines, and functions.
"main" is the primary code segment where the program begins its execution. Typically the "main" contains all the necessary code sequences that executes from the beginning and the program will terminate after the last statement in the "main". Many programming languages require the existence of "main" (e.g., C, Visual Basic, Java, etc.). It was evident from the beginning days of programming that there were tasks that needed to be performed "more than once". Rather than rewriting the same code over and over and placing it in the "main", a method of reusing "pieces of code" was needed. This was accomplished by:
Early languages typically contained a starting routine -- named "main"; followed by many "subroutines" -- each having a unique name that are "called" when needed. So a program layout might apear as:
MAIN ...code execution begins here . . sequence of instructions . . call fred . . call alice . . . call fred . . END MAIN SUBROUTINE fred ...code execution begins here for fred . . sequence of instructions . END SUBROUTINE SUBROUTINE alice ...code execution begins here for alice . . sequence of instructions . END SUBROUTINE In this example, the instructions are executed sequentially in "main". When a "call" is encountered, the program jumps from "main" to the top of the named "subroutine"; then sequentially executes the code in the "subroutine"; when the "subroutine" code is completed the program "returns" to the line following the calling statement. This is a powerful idea that allows code to be reused without having to be rewritten. Further, suboutines were also allowed to "call" other subroutines, making complex task sequences much easier to organize. The actual geography of the "main" and the "subroutines" varied in the early programming languages. Some required that the "main" appear first and in some languages it appears last (e.g., PASCAL). Another primitive feature of programming languages was the concept of a "function". The idea is that the code contained in a function would produce a "result". The originally arose from the need for mathematical operations like square root, sin, cosine, etc. that were often used many times in programs and always produced a simple result (in the case of the mathematical functions -- a single number). So, this third class appeared as a different type of subroutine -- instead of a "sub" routine that performed a task, the "function" routine produced a numeric result that was to be "returned" to the calling routine. [We must attribute this idea -- as well as If-Then-Else, Loops, and darn near everything else about computing -- to Alan M. Turing who first "used" these ideas in the 1940s. See this]. Thus, complex mathematical calculations could be simplified. For example, Euler's formula: sin(x+y) = sin(x)cos(y)+cos(x)sin(y) could be expressed programmatically as: sinxy = sin(x) * cos(y) + cos(x) * sin(y)by having two functions: sin() and cos() available that "returned" trigonometric values that are then used on the right-hand side of the equation to calculate a subsequent result. This example highlights the need not only to "return" values from a routine (either "subroutine" or "function") but also the need to "pass" values into a routine. The idea of "passing" values to a routine was codified by passing one or more "arguments" -- i.e., sending one or more data values to a routine. The "argments" can take the form of either "variables" or "constants". The general layout for subroutines is: the "call" verb; followed by the subroutine "name"; a left parenthesis; zero or more "arguments" that may be either "variables" or "constants"; followed by a closing right parenthesis. Like this for "subroutines": call some_subroutine_name ( variable or constant , variable or constant , ...) and like this for "functions": variable = some_function_name ( variable or constant , variable or constant , ...) You should notice that "subroutines" may be passed values -- but they do NOT return values. "functions" may be passed values and DO "return" values. Early languages like FORTRAN and BASIC made this distinction between the two types of routines. Ken Thompson and Dennis Ritchie in their development of the C programming language simplified this issue by doing away with the concept of of a "subroutine" and made the "function" two serve BOTH purposes by having a "void function" return no value (i.e., it acts like a subroutine) and non-void functions (e.g., int function, float function) that do return values of a specific type. Thus, C-based languages DO NOT have subroutines whereas FORTRAN- based languages like BASIC do utilize the call-subroutine structure. In our two languages (vbscript and javascript) we have a few specific differences.
| |
VBscript |
Javascript |
|
|
Scope: Local and Global When variables and objects are defined in a subroutine or function, their "scope" are said to be "local". This means that the value of the variable is NOT directly accessible from other subroutines and function -- i.e., you CANNOT get or set its values outside the subroutine or function where it is defined. Thus, a "local" variable lives only inside the subroutine or function where it is defined. One may "pass" the value of a "local" variable to another subroutine or function -- but it must be explicitly done. In order for a variable to be visible (meaning you can get or set its value) to other subroutines and functions it must define "outside" any subroutine or function. This makes the "Scope" of the variable "global" (i.e., You can get or set the value of any "global" from ANY inside any subroutine or function. This is normally done at the beginning of the code like this:
var x; var y=10; function fred() { var mary=88; //***this assigns the value 88 to the local variable named mary . . x=10; //*** this assigns the numeric value 10 to the global variable named x . . } function alice() { . . john = y*34; //*** uses the value of the global variable named y . . } The obvious advantage of "global" variables is that you do NOT have to pass their values in calling statements to other procedures. One must, however, exercise considerable caution when making "global" variables. |