ZBasic Language Reference
78
ZX Microcontroller Family
When thinking about Program Memory data tables, on the other hand, the perception does matter
because the initializer data is arranged in rows and columns and you need to know how to get the array
element that you want. To do so, always specify the column index first and the row index second. This
order was adopted to maintain compatibility with the BasicX compiler.
3.17 Recursion in Subroutines and Functions
A subroutine or function may be invoked recursively. This means that among the statements in the
routine there is one or more that invokes the same subroutine or function again, either directly or
indirectly. Clearly, the recursive invocation must be conditional so that at some point the recursion
ceases.
In Section 2.3.2, Defining Functions, an example function was given for computing factorial. Here is the
same function written using recursion.
Function Factorial(ByVal val as Integer) As Integer
If (val > 1) Then
Factorial = Factorial(val - 1) * val
Else
Factorial = 1
End If
End Function
Although it may look confusing at first, the logic is fairly simple. The idea is based on the fact that the
value of N factorial is equal to N times the factorial of (N-1). That logic is directly expressed in the second
line of code. Note that the identifier Factorial is used in two distinctly different ways in the second line
of the function. On the left side of the equal sign, the identifier Factorial refers to the return value
variable while that on the right side of the equal sign is a recursive invocation of the Factorial function
itself. The compiler is able to distinguish the two uses by the presence of parentheses following the
name. Since the return value variable can never be an array, the two types of references are easily
distinguishable.
The negative aspect of recursion is that it can consume a large amount of stack space. Each time a
function or subroutine invocation is performed, the processor allocates additional stack space. The extra
space is used to hold some tracking information to allow the processor to return to executing the code
that immediately follows the invocation. Also, stack space is required for any parameters that are passed
to the subroutine/function and for any variables that are defined inside the subroutine/function. Lastly, in
the case of a function only, stack space is required to hold the return value from the function. Clearly,
Factorial(10000) would require more stack space than is available even if all the RAM were
dedicated to the stack.
BasicX Compatibility Note
The BasicX compiler does not allow direct recursive invocation of
a function but the BasicX mode of the ZBasic compiler does.
3.18 Using Default Parameter Values in Subroutines and Functions
ZBasic supports the designation of default values for parameters to subroutines and functions. This
saves time when typing statements and makes the code easier to read when a particular routine is
usually invoked with one or more parameters having the same constant value. Specification of the
default value is done by adding an equal sign and a constant expression following the type specification
of the formal parameter in the routine definition as illustrated in the example below. In the first call to the
subroutine foo, the second parameter is omitted so the compiler automatically adds the specified default
value for the second parameter.