The function declaration can be placed anywhere in the code before or after the function is used. Because the functions just as well as the variables are typeless there is no such thing as function prototype and thus functions can not be declared beforehand.
You can call a function in your BASIC code that is not defined yet. The syntax analyzer seeing the function_name() construct will see that this is a function call and will generate the appropriate code to call the function that is defined later. If the function is not defined until the end of the code then the interpreter will generate error before the code is started.
Functions just as well as subroutines can have argument and local variables. When the function or subroutine is called the actual values are evaluated and placed in the argument variables. It is not an error when calling a function to specify less or more number of actual arguments than the declared arguments.
If the actual arguments are too few the rest of the arguments will become undef before the function starts. If there are too many arguments when calling a function or subroutine the extra arguments are evaluated and then dropped (ignored).
ScriptBasic allows recursive functions thus a function can call itself, but a function or subroutine is not allowed to be declared inside of another subroutine or function.
Functions differ from subroutines in the fact functions return value while subroutines do not. However in ScriptBasic this is not a strict rule. Subroutines declared with SUB instead of FUNCTION are allowed to return a value and been used just as if it was declared with the keyword FUNCTION.
To return a value from a function the name of the function can be used just like a local variable. The assignment assigning a value to the function will be returned from the function. If there are more than one assignments to the function name then the last assignment executed will prevail. On the other hand you can not use the function name as a local variable and retrieve the last assigned value from the function name. Using the function name inside the function in an expression will result recursive call or will be used as a global or local variable.
If the actual value of an argument is left value then the reference to the actual argument is passed to the function or the subroutine instead of the value. In other cases the value of the expression standing in the position of the argument when calling the function is passed.
Passing a variable by reference means altering the argument variable also alters the variable that was passed to the function.
To force a variable passed by value rather than reference the operator ByVal can be used. When ByVal is used as a numeric operator in an expression acts as an identity operator. It means that the value of the expression is the same as the value standing on the right of the operator ByVal. However this is already an expression and not a variable and as such it can not be passed by reference only the value.
The keyword ByVal can also be used as a command listing all the argument variables after the keyword on a line:
function myfunc(a,b,c,d) ByVal a,b,c ...
In this case ByVal acts as a command and replaces the references by copies of the values. After executing this command the argument values can be altered without affecting the variables that stand in the argument's place where the function is called.
Although the command ByVal looks like a declaration of arguments to be passed by value instead of reference; this is not a declaration but it rather a command that has to be executed.