For BBj-specific information, see DEF Verb
The DEF verb declares a user-defined function. DEF must be the first command on a line and may not be preceded by a label.
Series of simple variables separated by commas
If an expression follows the argument list, the function is complete
on one line. If there is no expression following the argument list, the
function occupies multiple lines and is not complete until the execution
of a RETURN. If a multi-line function encounters an FNEND command, an
!ERROR=24 is reported.
When PRO/5 encounters any FNnumname or FNstrname in an expression during program execution, it locates the corresponding DEF statement and evaluates the function. The DEF statement can be placed anywhere in the program; however, they are traditionally placed near the top of the program.
A DEF statement is skipped in normal execution, and a multi-line function is skipped by proceeding to the next FNEND command in the program.
The arguments given in the function call must match the corresponding argument list in the DEF by number and type. Unlike many BASICs, arguments listed in the DEF statement are not dummy arguments.
In the following example, when executing FNA(4) in line 20, it assigns the value of 4 to the variable Z:
0010 DEF FNA(Z)=Z*5
0020 LET Y=FNA(4)
Do not define the same function more than once in a program because the result is unpredictable. PRO/5 distinguishes between FNA() and FNA$(), and both can exist in the same program.
If a DEF statement does not contain an "=" followed by an
expression, then it is the first line of a multi-line function. The body
of the function consists of the following lines until the next FNEND statement.
A FNEND statement must be on a line by itself. If a multi-line function
is encountered during normal execution, it is skipped just as a normal
single-line DEF statement would be.
A function result is returned by a RETURN statement:
NOTE: The developer must take
care not to allow the function logic to flow off the end of the function.
It is never valid to execute
a FNEND statement.
The TCB(17) function returns the current nested level of multi-line functions.
The following example is a simple multi-line function that returns the greatest common factor of two integers. A test will be made to ensure that the two arguments are valid integers.
100 DEF FNGCF(X,Y)
110 IF FPT(X)<>0 OR FPT(Y)<>0 THEN FNERR 41
120 WHILE X<>0
130 LET TEMP=X, X=MOD(Y,X), Y=TEMP
150 RETURN Y
Error Handling in Multi-line Functions
If an untrapped error occurs during a multi-line function, the error
is reported at the location where the function was called. Inside a multi-line
function, errors may be trapped with the standard ERR=, DOM=, and END=
clauses. The global SETERR is ignored during the execution of a multi-line
Occasionally it is desirable to generate an error condition to be passed back to the invocation point. This is done with the FNERR statement:
200 IF A<0 THEN FNERR 40
This is analogous to the EXIT ERR statement in a public program.
Restrictions in Multi-line Functions
Generally, multi-line functions are intended to perform some kind of
calculation and return. It is legal to perform I/O in a multi-line function,
but the developer must exercise caution. If such a function were called
from an I/O operation, the results of the I/O operation might not be as
The following operations cannot be performed in a multi-line function:
The function cannot perform any kind of reset operation such as BEGIN, CLEAR, RESET, or START.
A BACKGROUND, CALL, OPEN, CLOSE, SAVE, or RUN cannot be executed.
Console mode cannot be entered with an ESCAPE, END, or STOP.
NOTE: Integer functions, such as DEF FNA%(X), are not supported.
PRO/5 does not permit DEF in console mode, and it cannot be part of a compound statement.
The example below illustrates declaring a multi-line function that translates global strings:
0100 DEF FNSETPATH$(X1$)
0120 LET P1=POS("("=X1$,-1)
0130 IF P1=0 THEN RETURN X1$
0140 LET P2=POS(")"=X1$(P1))+P1-1
0150 IF P1>=P2 THEN RETURN X1$
0160 LET X2$=$$
0170 LET X2$=STBL(X1$(P1+1,P2-P1-1),ERR=NAME_NOT_THERE)
0190 LET X1$=X1$(1,P1-1)+X2$+X1$(P2+1);
If the global string (DICT) has the value "/basis/taos/datad/", then: