The language includes user-defined subroutine (Sub) and function (Function) procedures. Functions are identical to subroutines except that a function returns a value and a call to a function can be included in an arithmetic or string expression. Except as noted in this document, “procedure” or “routine” refer to both user-defined procedures and functions.
A Function or Sub may be invoked by placing its name as the first item in a statement or by using the Call keyword. If a Function is invoked in this manner, the returned value of a Function is ignored. In addition, a Function, but not a Sub, may be embedded in an expression whose type is consistent with the type returned by the function.
When invoking either a Sub or a Function, parentheses must always be provided around the argument list, with empty parenthesis supplied if there are no arguments. In VB6, parentheses are required if a Call is used and forbidden if a Call is not included. In VB.Net, parentheses are only optional for empty argument lists, although the Visual Studio.Net editor always inserts parentheses.
The following are some valid examples:
Call MyProcedure (1, 2, 3) ' ()always required for non-null args
MyProcedure (1, 2, 3) ' Call is optional
x = 2 * MyFunction (y)
MyFunction(y) ' Do not care about the value
When a procedure is executed, the procedure exits and returns control to the calling routine when one of the following is encountered:
1. The end of the procedure, marked by an End Function or End Sub statement.
2. An Exit Function or Exit Sub statement, depending on the procedure type
3. A Return statement.
If the top-level procedure exits, execution of its thread is terminated.
The returned value of a Function is specified by either an expression argument to the Return statement or by assigning a value to the function name as if it were a variable. For example:
Function Test (ByVal x As Double) As Double
If x < 10 Then
Return x+1 ' Exits with a value of x+1
Else
Test = x+2 ' Sets the return value to x+2
Exit Function ' Exits with the current return value
End If
End Function
All arguments (including arrays and objects) can either be passed to a procedure by value (ByVal) or by reference (ByRef).
For numeric, Boolean and String types, ByVal means that a copy of the value is made for the called procedure. The called procedure may freely modify the argument variable without affecting the value in the calling program. By default, all arguments are passed ByVal.
For numeric, Boolean and String types, ByRef means that a pointer to the variable containing the value is passed to the called program. Only variables can be passed by reference. When the called procedure modifies its argument variable, it is actually modifying the value in the calling program.
Passing objects ByVal and ByRef has some subtle differences. In both cases, accessing and modifying members of the object have the same effect and change the same data. They are different for the case when you assign directly to the procedure argument. In the ByVal case, you only change the pointer to the value in the called procedure. In the ByRef case, you change the pointer to the value in the calling procedure’s object variable.
The language does not support the GoSub statement. This statement allowed an arbitrary line within a procedure to act as the start of a procedure embedded within a procedure. Also, the language does not support declaring a procedure as Static. A Static procedure forced all of the local variables of a procedure to be statically defined such that they retained their values between calls. Variables must be individually specified as being Static.
GPL does not support Optional procedure arguments, initial argument values, or the ParamArray keyword. It also does not support passing a Set or Get Property as a ByRef argument.