If a REXX function (or subroutine) does not need to use the variables which the rest of the script creates, or if the function uses variables which the rest of the script does not need to access, then you can start the function with the PROCEDURE instruction. This clears all the existing variables away out of sight, and prepares for a new set of variables. This new set will be destroyed when the function returns. The advantage to this is that it ensures that the function won't ever alter the value of any variable used by the rest of your script, even if the function creates a variable with the same name as one used elsewhere in your script (ie, the variable in the function belongs to an entirely different set of variables than the one with the same name elsewhere). Likewise, if a function calls another function which contains the PROCEDURE instruction, that second function won't alter the values of any variables used by the first function. So, PROCEDURE is a way to protect variables from being inadvertently altered by calls to functions or subroutines.

The following script calculates the factorial of a number recursively. PROCEDURE makes recursion possible and easy.

/* Calculate factorial x, that is, 1*2*3* ... *x  */
SAY "Enter a number"
PARSE PULL num .
SAY num"!="factorial(num)
EXIT

factorial: /* calculate the factorial of the argument */
   PROCEDURE
   PARSE ARG num
   IF num<3 THEN RETURN num
   ELSE RETURN factorial(num-1) * p
First of all, the num variable initially passed to factorial is not the same num variable used within factorial (ie, in the PARSE ARG instruction) due to the PROCEDURE instruction. So, that PARSE ARG isn't altering the original num variable, but rather, creating a new variable named num. Furthermore, that second num variable is then passed to factorial again. (ie, factorial calls itself when it goes to return a value). When factorial is called again, it creates yet another num variable to be used up until that nested call returns.


Exposing variables

If the subroutine or function needs access to just a few variables used elsewhere in the script, but wants to protect all other variables, then put the EXPOSE keyword after PROCEDURE, followed by any variable names that you don't want hidden away. In this way, your function can alter the values of particular variables used elsewhere in the script, while also protecting other variables. Consider the following:

/* Assign values to variables First and Second */
First = 0
Second = 0
/* Call subroutine alter */
CALL alter
SAY "First =" First", Second =" Second
EXIT

alter:
   PROCEDURE EXPOSE First /* don't protect the variable First */
   First = 1
   Second = 1
   RETURN
The above prints out "First = 1, Second = 0". Note that the alter subroutine was able to change the value of First used in the SAY command, but not the value of Second. That's because the Second variable that alter changes is an entirely different variable than the Second variable used elsewhere in the script. On the other hand, the First variable used within alter is the very same one used elsewhere.