The function calling mechanism is identical with that for subroutines. The only difference between functions and subroutines is that functions must return data, whereas subroutines need not.
The following types of routines can be called as functions:
If you are calling an internal routine as a function, you must specify an expression in any RETURN instruction to return from it. This is not necessary if it is called as a subroutine.
/* Recursive internal function execution... */
arg x
say x'! =' factorial(x)
exit
factorial: procedure /* Calculate factorial by */
arg n /* recursive invocation. */
if n=0 then return 1
return factorial(n-1) * n
While searching for an internal label, syntax checking is performed and the exec is tokenized. See Appendix I. Performance Considerations for more details. FACTORIAL is unusual in that it calls itself (this is recursive invocation). The PROCEDURE instruction ensures that a new variable n is created for each invocation.
The search order for functions is: internal routines take precedence, then built-in functions, and finally external functions.
Internal routines are not used if the function name is given as a literal string (that is, specified in quotation marks); in this case the function must be built-in or external. This lets you usurp the name of, say, a built-in function to extend its capabilities, yet still be able to call the built-in function when needed.
/* This internal DATE function modifies the */
/* default for the DATE function to standard date. */
date: procedure
arg in
if in='' then in='Standard'
return 'DATE'(in)
Built-in functions have uppercase names, and so the name in the literal string must be in uppercase for the search to succeed, as in the example. The same is usually true of external functions.
External functions and subroutines have a system-defined search order. The search order for external functions and subroutines follows.
Whenever an exec, command, external function, or subroutine, written in REXX is invoked by REXX/CICS (for example: from the CICS command line, CALL instruction, EXEC command, or a command from within an exec), the search order for locating the target exec is as follows:
If the user is an authorized user or if the current exec was loaded from a sublibrary specified on the last SETSYS AUTHELIB command and the search is for an authorized command's program, then check the sublibraries specified on the most recent SETSYS AUTHCLIB command.
If an external or built-in function detects an error of any kind, the language processor is informed, and a syntax error results. Execution of the clause that included the function call is, therefore, ended. Similarly, if an external function fails to return data correctly, the language processor detects this and reports it as an error.
If a syntax error occurs during the execution of an internal function, it can be trapped (using SIGNAL ON SYNTAX) and recovery may then be possible. If the error is not trapped, the program is ended.