Assume that you have written a function called TestFunction() that gets passed some args, and returns a value to the script. Your return value will be the string "done".

The REXX script must do something explicitly with that value. For example, the script may assign it to a variable as so:

MyReturn = TestFunction('Arg One', , MyVariable, "Arg 4");
Or, the script could use it as the argument to another REXX instruction/function. For example, here it is used as the argument to the SAY instruction:
SAY TestFunction('Arg One', , MyVariable, "Arg 4");
Here it is used as the argument to the IF instruction, in an expression to evaluate:
IF TestFunction('Arg One', , MyVariable, "Arg 4") = "done" THEN EXIT;

But, what if the REXX script doesn't explicitly do anything with the return value from your function, as so?:

TestFunction('Arg One', , MyVariable, "Arg 4");

Unlike with C, that return value doesn't remain unused. Instead, what Rexx does is pipe your return value to the current Environment (ie, current Subcom Handler. We'll talk about Subcom Handlers elsewhere). By default, this is the operating system shell. The net result is that your return string "done" gets passed to the operating system shell as a command, and the operating system thinks that the REXX script wants to run some program called "done".

Obviously, unless the script writer intends for this behavior, then he must either explicitly do something with your return value, or explicitly throw it away. We've already seen above how he can explicitly do something with it. But how does he explicitly throw it away?

To explicitly throw away your return value, the script must use the CALL keyword to call your function as if it were a subroutine. All this really entails is putting the CALL keyword in front of the name of the function, and omitting the parentheses around the arguments, as so:

CALL TestFunction 'Arg One', , MyVariable, "Arg 4";

NOTE: Reginald supports keeping the parentheses around the args passed to your function, while using the CALL keyword. Other interpreters may not support this.

Actually, the return value is not technically thrown away. When a script calls your function as if it were a subroutine, any REXX string you return to the script will (temporarily) be assigned to the special RC REXX variable in the script (until the script calls another function). But, the important thing is, at least your return value is not piped to some Subcom Handler.

Alternately, the REXX statement ADDRESS NULL may be added to the top of the script, and then the script can toss your return value away much like in C -- without needing the CALL keyword, and keeping the parentheses, as so:

ADDRESS NULL
TestFunction('Arg One', , MyVariable, "Arg 4");

NOTE: Reginald allows your program to set the proprietary NULL OPTION to prevent a REXX script from accessing any Subcom Handler except your own. If you haven't registered your own Subcom Handler, then this is tantamount to the ADDRESS NULL statement above. But, this prevents the script from running other programs or issuing commands to the operating system shell. Alternately, a user can use Reginald's REXX Administration Tool to enable "Default environment of NULL". This is tantamount to including the ADDRESS NULL statement in every script he runs.