Subroutines and functions, what exactly is the difference? They're very similar, but they're not the same. First, a function absolutely must return a value to the calling program, otherwise the program fails. A subroutine, on the other hand, may or may not return a value to the cooler. Second, when a function returns its value, the value replaces the function call in the calling program. If the subroutine returns a value, the value is automatically assigned to the special Rexx variable called result. Finally, the function is recognized by the left parentheses that immediately followed the function name. A subroutine is invoked with Rexx instruction call. All functions can be invoked with a call instruction, so all functions can be used as subroutines. As subroutines are not required to return a value, not all subroutines can be invoked as functions. Functions and subroutines, which will collectively call sub procedures are necessary to maintain a structured programming paradigm and to avoid this spaghetti code of non-structured programming languages. You can often modularize a program with each module being written as a sub procedure, the mainline portion of the program, then we're just place calls to these various sub procedures where the real work takes place. Using this sub procedures allows you to execute the same code from various parts of your program without having to rewrite the same lines of code over and over again. As it can be external to your program, it also allows you to reuse the same code in several different programs that need to perform the same tasks. Once Rexx knows it has to look for a sub procedure, it does exactly the same thing, whether it's a subroutine or a function. First, it looks for the name of the sub procedure as a label in the currently executing exit. This is an internal sub procedure. A label is a name or symbol immediately followed by a colon. If the label is found, control is transferred to the label and the Rexx instructions following the label are executed until the return keyword instruction is encountered. The return instruction will cause Rexx to return control back up into the mainline program. If a function is being executed, return must be followed by an expression which will be evaluated. This will become the value the function returns to the main program. If a subroutine is being executed, then the return instruction does not have to be followed by a value. If a value is returned, it will be assigned to that special Rexx variable result in the main program. The sub procedure itself is coded in much the same way, whether it's a function or a subroutine. The difference is whether or not it must return a value to the calling program and functions, as I've said, must return a value, subroutines may or may not. The small dotted purple line in the visual, shows the flow of control for a subroutine call, and the larger dashed blue line shows the flow for a function. As all functions can be called a subroutines, the same sub procedure is being used in both cases. Now, notice the exit instruction before sub procedure. This prevents accidentally falling through into the internal sub procedure code. A return instruction could have been used here instead. The procedure instruction is used to prevent [inaudible] automatically sharing variables between the main program, and internal sub procedure. The programmer has complete control over how much variable sharing is to take place. As an internal sub procedure is part of the program itself, by default, Rexx will share all variables in the main program with the internal sub procedure. Also, all variables created in the internal sub procedure are automatically shared with the main program. Coding the procedure instruction with no other keywords causes Rexx to prevent any and all variable sharing with the internal sub procedure. You can think of it as Rexx closing the in-memory table of variables and their values for the main program and creating a new empty table for the sub procedure to use. When the sub procedure ends with the return instruction, Rexx deletes the sub procedure table of variables and restores the main program table. Therefore, no variables are shared between the main program and the internal sub procedure. Adding the keyword exposed to the procedure instruction allows the programmer to share some variables, but not others. Only those variable names coded following the keyword exposed are shared between the main program and internal sub procedure. If unexposed variable is modified in the sub procedure, it's value is also modified in the main program. The variables named after the keyword expose can be created in either the main program or in the sub procedure. As your application grows, you may wish to place some procedures in separate members of the PDS concatenation. This also facilitates reusing code in multiple programs. The return and exit keyword instructions will both act in the same way here. They'll both return control to the calling program. Internal sub procedures can use Rexx naming rules, that same rules as for variable names, but external ones must conform to PDS member naming rules, that's one to a character Alpha numeric, or the national set, and the first character cannot be a number. A Rexx program is all of the code within one member of a dataset and it uses one pool of variables. Another program gets another pool of variables, so you will not have conflicting variable names. This means that an internal sub procedure can and will share variables with the main program, and that's the procedure instruction is used. But an external one cannot. The variables in the main program are not available to an external sub procedure, and the variables in an external sub procedure are not available to the main program. This provides a greater level of isolation and integrity for complex applications. When a subroutine returns a value, it is returned to the Rexx special variable called result. When a function returns a value, it replaces the function call. Remember that while functions must return a value, subroutines do not have to. We already said that a sub procedure can be passed up to 20 arguments. We also said that the arguments are actually called argument strings. Each argument string is in a novel itself, Rexx expression. What is Rexx expression? Think you might have heard me say this before. It's a combination of literals, variables, functions, and other operating characters. They're called argument strings because they can each be a string containing multiple words of data. Just as input arguments passed to an executive from the command line are received by the path Arg instruction. The argument string passed by a sub procedure, are received by a Parse Arg instruction as well. The Parse Arg instruction contains a parsing template which describes how the input arguments are to be broken up and assigned to variables. In a call to a sub procedure, each comment eliminated arguments string is passed separately by multiple comment eliminated parsing templates coded in the Parse or instruction. The Arg function can be used to parse multiple input arguments strings as well. When invoking in an exec as though it were a command, only one command string is allowed. Let's take a quick look in some examples, here in the call instruction, each comment deliminated arguments string is first evaluated by Rexx, and the result of these evaluations are then passed to the subroutine. The Parse Arg instruction in the subroutine passes each argument string with it's own comment deliminated passing template, so Parse Arg var1, 2, 3, 4, assigns one to var1, two var2, three to var3 and four to var4. The Parse Upper example translates all incoming data to uppercase, so var1 is uppercase 1. In the third example, notice how a comma is missing between var1 and 2. That will result in var2 being assigned a null value. This time, notice the call instruction is missing a comma between the arga, argb, and between argc and argd arguments. The first argument string arga and argb, is passed to the first passing template in the subroutine, which is var1. This variable received the entire argument string, so is assigned the string 1 and 2. The second and third argument strings are passed in a similar fashion. Only three arguments strings are passed to the subroutines. The fourth passing template, var4 has no data to receive and so is assigned a null value. There we have it, subroutines and functions. Your tolls for maintaining a structured programming paradigm.