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:

  1. creating a separate identifable set of the instructions (called a "subroutine"). This descriptive name implies that instructions are NOT the "main" routine, but a "sub" routine.
  2. giving the subroutine a "name".
  3. and then have a method for causing the subroutine to be executed when needed. The verb chosen was "call".

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.

  • there is no "main" in browser scripting

    The process for invoking the script code (i.e., causing script to be executed) is based on user events -- like clicking and mouseovers. There is no "main" program that is execute from beginning to end at the time the page is loaded. All scripting activity is based on being a response to a user's action (an event). As a result, browser scripts are generally composed of small snippets of code (functions or subs) associated with specific user generated events. Each "event then code excution" is a separate task. There is no grand sequence of events (i.e., "main") that is performed once every time the page is loaded as in the "batch" processing programs typical of pre-browser applications.

  • subroutines and functions

    Both vbscript and javascript use functions in the same general fashion. The specific differences between the two languages are discussed below. Only vbscript allows a subroutine -- as discussed above, javascript's C-based approach combines the subroutine and function ideas into a single approach based on functions.

 

 
VBscript
 
 
Javascript
 
  • subroutine

    The general structure of a vbscript subroutine is:

    sub name_of_subroutine ( arg1, arg2, arg3,..)
    .
    ....any vbscript statements
    .
    end sub
    

    The name_of_subroutine must begin with an alphabetic character; contain no spaces and cannot start with a number. The parentheses and arguments are optional. The subroutine is invoked by:

    .
    .
    .
    call name_of_subroutine ( arg1, arg2, arg3,..) 
    .
    .
    .
    OR
    .
    .
    .
    name_of_subroutine  arg1, arg2, arg3,... 
    .
    .
    .
    

    Again the parentheses and arguments are optional. However, if you use the vbscript verb "call" and you are passing arguments you must enclose the arguments in parentheses. If you omit the "call" verb, NO parentheses are required if you pass arguments. If you are passing NO arguments and you use the "call" verb you can use either empty parentheses or not. You may also omit the "call" and use just the sub's name if you are passing NO arguments. The following calls to a subroutine are valid:

    call fred
    call fred()
    fred
    call alice("abc",7)
    alice "abc",7

    There exists and exit sub statement that allows you to leave the subroutine and return to the calling routine. This may appear anywhere in the subroutine and may appear more than once.

  • function

    Functions in vbscript are used to modularize (separate) reusable code. Most all built-in vbscript features are structured as functions (see vbscript on the left side of the sequentials page). The general structure of a vbscript function is:

    function name_of_function ( arg1, arg2, arg3,..)
    .
    ....any vbscript statements
    .
    name_of_function = expression or value
    end function
    

    The name_of_function must begin with an alphabetic character; contain no spaces and cannot start with a number. Note the structure appears similar to the subroutine layout -- EXCEPT the name_of_function is assigned a value somewhere in the body of the function. There is also an exit function statement that allows you to return to the calling program at anytime.

    The function uses parentheses because it is expected to be passed at least one argument.

    A function is referenced in the calling routine by its name and must appear on the right-hand side of an assignment statement. It is permissible to reference a function just like a subroutine by using the "call" verb, however, if the function returns a value it is ignored.

  • Passing Arguments

    There are two ways to pass arguments to subs and functions:

    1. pass by reference (this is the default)

      The default method for passing arguments to subs and functions is "by reference". This means that for the arguments that are variables, the address of the variable is passed to the sub ior function. If the sub or function modifies the argument, it is also modified for all subsequent references in the calling routine. Modifying the address modifies the varibale everywhere. Consider this example:

      .
      .
      x=32
      call alice(x)
      .
      .
      .
      sub alice (h)
         h=h+4
      end sub
      .
      .
      .
      
      Here the variable x is assigned a value of 32 and passed as an argument of a call to alice. What is passed is the "address of x" -- not the value of "x". In the sub named alice, the variable "h" is assumed to be at the located in memory at the "address of x". Adding 4 to "h" thus adds 4 to the variable stored at "the address of x" -- i.e., "x" gets modified in the sub.

    2. pass by value

      The other method for passing argument values to subs and functions is to "pass by value". In ths method the value of the argument to be passed is copied from memory and only the value is passed to the sub or function. Consider the example above -- but with the ByVal option used for the passing argument:

      .
      .
      x=32
      call alice(x)
      .
      .
      .
      sub alice (ByVal h)
         h=h+4
      end sub
      .
      .
      .
      

      In this case, the value of "x" (i.e., 32) is copied and assigned to the variable "h" in the sub named alice. On the return to the calling routine, the value of "x" HAS NOT BEEN CHANGED. The variable "h" in alice is in a different place in memory -- so any change in "h" is NOT reflected in "x". Thus, "Pass by value." You have to explicitly request this option by using the ByVal option on every variable passed to a function or sub.

      There is also a ByRef preface for arguments. But because it if the default, it is not required to be used.

  • "Number, type and order" does not apply

    The old programming adage for argument passing is that "arguments must agree in number, type and order". This means that the the number, type and order of argument specified in a calling statement must agree with the number, type and order of arguments in the called routine. This is only partially TRUE for vbscript and javascript. Generally, if the calling routine specfies three arguments -- then there should be three arguments specified in the called routine. If the calling routine passes a string, an integer and a floating point number, then the called routine should recive the same three data type. The last rule says that the order does not change. BUT vbscript and javascript are "loosely typed" languages (i.e., the data type depends on usage -- not on a fixed declaration like compiled languages).

  • in-line code

    Typically vbscript code is placed in subs or function inside script tags in the head of the HTML page. However, for short code snippets it is possible to place code on the HTML page itself. This requires using a user event (such as onClick) where the code statements are placed inside the quotes of the event value. Here is a link with vbscript in-line code:

    <a href="#" onClick="vbscript: k=sqr(3.14159): msgbox 'Square Root of pi='+cstr(k):">Click here for the square root of pi</a>

    renders as:

    Click here for the square root of pi

  • function

    The javascript function uses the following structure:

    function name_of_function ( arg1, arg2, arg3,..)
    {
    .
    ....any javascript statements
    .
    return  expression or value
    }
    

    The use of arguments is optional. If you do not pass arguments you still must provide empty parentheses.

    The "return" statement is also optional. It is used when you wish to return a value to the calling routine. Note that the "return" statement does not have an equal sign separating the word "return" from the expression or value whose value is to be returned. Also you may use a "return with no "value" or "expression". This form of a function behave like a subroutine "call" in vbscript.

    The function is called by:

    function name_of_function ( arg1, arg2, arg3,..);

    The function call may appear as an entire statement on a line by itself. In this case the function does NOT return a value (i.e., the called function would have NO "return": statement or a "return statement with no "value" or "expression". In the case where the function does return a value, it may appear on the right-hand side of an assignment statement in an expression.

  • passing arguments

    • pass by value (appears to be the default)

      When javascript functions use primitive types like String; Number; Undefined; Null or Boolean as arguments, the values are "passed by value". This is the default behavior for primitive types only. Thus, when the arguments are primtives and passed to a function -- only the values are passed. Any change to a variable inside the function DO NOT modify the variable in the calling routine. For example:

      .
      .
      x=32;
      new_x=alice(x)
      .
      .
      .
      function alice (h)
      {
         h=h+4;
         return h
      }
      .
      .
      .
      

      Here the value of "x" is passed to the function "alice" and assigned to the variable "h". A four is added to "h" and returned. The value of "new_x" in the calling routine is 36. The value of "x" in the calling routine is still 32. However, if the argument is not a primitive datatype, the default behavior is to "passed by reference". This occurs specifically for all other objects such as arrays. So be forwarned that if you pass an array and the function modifies the contents of the array that change occurs everywhere in script.

    • pass by reference is the default in general

      There is no explicit mechanism in javascript to provide for "pass by reference" as in vbscript. Javascript always passes by reference -- however -- this does not apply to primitives -- as stated above. Arguments about this are largely semantic. First, all data types in javascript are objects -- including the primitives like String and Number. So actually, javascript does pass all objects by reference -- but the description is actually -- "object references are passed by value" -- implying that this does not apply to primitives.

      Consider the four functions below. The "test" function creates three objects:

      1. an array named "w" with three elements all set to forty
      2. an object named "x" which is created and has a property named "numval" that is assigned the value of forty
      3. a variable named "y" assigned the value of forty

      Then, "test":

      1. passing the the array "w" to the function "add_44_to_all" that adds forty-four to each array element
      2. passes the object "x" to the function "add_44_to_numval" thats adds forty-four to the property "numval"
      3. passes the variable "y" to the function "add_44" that adds forty-four to the value of passed

      None of the functions return values. "test" then displays the results:

      1. All values of the original array "w" are now changed to 84, so the value passed must have been "pass by reference"
      2. The property "numval" of the original object "x" has changes to 84, so the value passed must have been "pass by reference"
      3. The value of "y" has NOT changed -- it is still forty , so the value passed must have been "pass by value"

      function add_44(z)
        {
         z = z + 44;
        }
      function add_44_to_numval(z)
        {
         z.numval = z.numval+44;
        }
      function add_44_to_all(z)
        {
         z[0]=z[0]+44;
         z[1]=z[1]+44;
         z[2]=z[2]+44;
        }
      function test()
        {
         var w = new Array (40,40,40);
         var x = new Object();
         x.numval = 40;
         var y = 44;
      
         add_44_to_all(w);
         add_44_to_numval(x);
         add_44(y);
      
         alert ("w="+w);
         alert ("x.numval="+x.numval);
         alert ("y="+y);
        }
      

      execute the code example above

  • in-line code

    Typically javascript code is placed in functions inside script tags in the head of the HTML page. However, for short code snippets it is possible to place code on the HTML page itself. This requires using a user event (such as onClick) where the code statements are placed inside the quotes of the event value. Here is a link with javascript in-line code:

    <a href="#" onClick="javascript: k=Math.sqrt(3.14159); alert ('Square Root of pi='+k); return false;">Click here for the square root of pi</a>

    renders as:

    Click here for the square root of pi

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.