sub - define a subprogram


sub Name[(Arg[, Arg]. . .)] static

[exit sub]

end sub


The sub statement begins the definition of a subprogram.  The definition ends with the end sub statement.  Name is the name of the subprogram used to identify the subprogram when it is called.  The subprogram may be called from another module.  In fact, the subprogram may be called from a language other than BASIC. 

Arg is a variable name or an array name followed by a single parentheses enclosed constant which represents the number of dimensions in the array.  An Arg in the definition of a subprogram is known as a formal parameter to the subprogram which will be replaced with an actual parameter when the call to the subprogram occurs.  The formal parameters are associated with the actual parameters positionally, i.e., the first formal parameter is associated with the first actual parameter, the second formal parameter with the second actual parameter, etc. Passing an argument to the subprogram is performed by reference, i.e., by an address where the actual value is stored.  If the argument passed is a simple variable, array element or an entire array, the address of the variable or array is passed.  This allows the subprogram to modify the variable or array. 

When the subprogram is referenced by a call statement, the arguments are evaluated (if necessary) and passed to the subprogram.  Within the subprogram, execution begins with the first statement after the sub statement and continues until the appearance of an exit sub or the end sub statement.  Control is finally transferred to the statement following the call statement. 

In general, the statements that may appear in a subprogram are the same as those allowed in the body of the program with the following notable exceptions.  The on error goto statement, if used, must reference a line number or label outside any subprogram or user defined function.  All other statements must not reference a line number or label outside the subprogram. 

Note that defining formal parameters actually redefines the meaning of those variables and array names within the subprogram.  By default, any variable that appears within a subprogram is different from a variable with the same name and type outside that subprogram.  That is, the scope of a variable within a subprogram, formal parameter or not, is limited to the subprogram.  If a variable that is not a formal parameter first appears in a shared statement, this default is overridden and the variable is the same as if it appeared outside the subprogram (see shared).  A variable might be declared "shared" before the subprogram definition begins using the word shared in other statements (see common, dim and redim). 

Any variable (formal parameter or not) may be declared or redeclared "static" explicitly with the static statement (see static).  So declared, the variable has scope limited to the subprogram.  Although it is the default, a variable used in a subprogram ought to be explicitly declared static because previous statements might have declared the variable shared (see above).  Declaring a variable static is a wise means of ensuring that the name one chooses for a variable used only inside a subprogram will not have mysterious side-effects on the rest of the subprogram. 

A subprogram definition may not appear within a subprogram or user defined function definition.  A subprogram may not be recursive, i.e., a subprogram definition may not contain a reference to the same subprogram.  Loop, conditional and subprogram and user defined function definition statements may not violate the boundaries of a subprogram definition, i.e. a multiline construct may not begin outside a definition and end inside or vice versa

A subprogram is available between modules and may not be defined more than once in the same program.  Subprogram parameter types are not compared between the definition and any of its references.  The opportunity for type mismatches and references to nonexistent arguments is present.  Within a subprogram, it is not possible to determine whether an array passed as an argument is static or dynamic; therefore, it is not possible to dimension or erase such an array (see dim). 


The following program:
	sub linreg(r2, a0, a1, x(1), y(1), n) static
		static x, y, xx, yy, xy, i

		if n = 0 then exit sub
		for i = 1 to n
			x = x + x(i)
			y = y + y(i)
			xy = xy + x(i) * y(i)
			xx = xx + x(i) * x(i)
			yy = yy + y(i) * y(i)
		next i
		xy = xy - x * y / n
		xx = xx - x * x / n
		yy = yy - y * y / n
		if xx = 0 or yy = 0 then exit sub
		a1 = xy / xx
		a0 = y / n - a1 * x / n
		r2 = (xy * xy) / (xx * yy)
	end sub

	data 0, 32, 100, 212, 37, 98.6
	for i = 1 to 3
		read cent(i), fahr(i)
	next i
	call linreg(r2, a0, a1, cent(), fahr(), 3.0)
	print "fahr =" a1 "* cent +" a0 ", r2 =" r2
defines a general purpose subprogram "linreg" which computes the linear regression for "n" pairs of data points.  The data are passed in two arrays, "x" and "y".  Three values are returned: the two parameters in the best linear equation relating the data and the square of the coefficient of correlation which indicates the quality of the relationship. 

This program uses three pairs of temperatures from the centigrade and Fahrenheit scales.  The data are passed to the subprogram which computes the relationship between the pairs in terms of a linear equation.  Because these pairs were selected deliberately, the coefficient of correlation is one indicating a perfect relationship.  Data in the real world will yield a value some degree less than one.  When executed, this program produces the following results:

	fahr = 1.8 * cent + 32 , r2 = 1 


call, common, dim, redim, shared, static, usr


A subprogram may also return a value, see usr for details. 

from The Basmark QuickBASIC Programmerís Manual by Lawrence Leinweber