REXX Newbies, Part V

By Chris Wenham

Summary: Functions let you take advantage of pre-written code that you don't have to understand the workings of. Nifty stuff, but first we'll show how to make a simple one of your own.

Functions
Catch-Up: If the instructions in this column make no sense to you then perhaps you need to freshen up on Rexx. Catch-up by reading these columns first:
 * Rexx Newbies: Part I, Part II, Part III, Part IV

A television set gives us a good example when we want to describe what a function is and does. With a TV, you supply it with data (the signal from the antenna), parameters to manipulate that data with (which channel and volume you want), and the TV returns its results (a picture and sound) after calculating and processing what it's been given.

It's a black box (literally, for most TVs) that we don't need to understand the innards of in order to make it work. But not all functions must be as complicated as a TV. You probably know how a flash light works, and could make one if you had the right materials at hand. If you've had training in soldering components to a circuit board and know enough high school level electronics you could probably assemble an FM radio too. And once either device has been put together, operation of it is much much simpler than the assembly of it.

It's like that in programming. Quite often you'll have a process that you need to make use of multiple times in the same program, or even in other programs too. Or, someone else will have written one that you'd like to make use of. Let's say you've written code that calculates how much you'd earn if you charged $10 per hour to build flash lights. Let's also assume that you want it to subtract expenses such as coffee and pretzels, which you consume at a regular rate while working and cost $1 per cup and $0.25 per packet, respectively. The code would probably look like this, assuming we've stored all those factors in variables already: Earnings = (hours * 10) - (hours * (1 + 0.25)) If you needed to calculate this several times in your program (we'll assume you make FM radios at $10 per hour too) it'd not only be more convenient, but it'd also reduce the chance of error if we could use the same code. And you can, if we package the code like this: CalcEarnings: procedure hours = arg(1) Earnings = (hours * 10) - (hours * (1 + 0.25)) Return Earnings Lets dissect this. The first line begins with "CalcEarnings:", the colon tells Rexx that this is the name of a function. Be aware that a function name must not contain any spaces. If you need to separate words, either use mixed caps like I did, or use an underscore (_).

The word after that colon, procedure, tells Rexx that this should be considered an independent module of code. In effect, it makes sure that variable names won't get mixed up. We can create variables within the function, name them whatever we like, and not have to worry about them conflicting with others that are outside and have the same name. procedure creates a new "sandbox" for the function to operate in.

The second line assigns the first parameter (argument) to a new variable called "hours". arg(1) retrieves argument number 1, and if you happened to need more than one argument/parameter you'd use arg(2) and arg(3) and so-on, putting them on new lines and assigning them to new variables.

The truth of it is, you could skip that "hours = arg(1)" part and just use "arg(1)" in place of the variable name "hours". But we want to get into the habit of doing it the wordy way early, since it becomes a pain in the rear to change all of those instances if you have a big function and want to insert another argument somewhere.

The last line, beginning with Return, tells Rexx to return the result of the calculation (stored in "Earnings") to whatever invoked it.

So how do you invoke it, and what exactly invokes it?

Remember how you learned to assign values to variables at the beginning of the series? We do exactly the same thing here, because now if you worked for 6 hours, the line of code that calls our new function "CalcEarnings" looks like this: Earned = CalcEarnings( 6)

And the result of all the calculations gets stored in the variable called "Earned"

Rexx sees the name "CalcEarnings", looks around in various places for a function called "CalcEarnings", and when it finds one it runs it. You just have to put the function where it can find it, the traditional place for user-defined functions being just after the main code of the program. Here's an example that spells it out: /* Calculate Earnings */ Say "How many hours did you work today?" Parse Pull Hours Earned = CalcEarnings( Hours) Say "You earned $" Earned Exit CalcEarnings: procedure hours = arg(1) Earnings = (hours * 10) - (hours * (1 + 0.25)) Return Earnings The "Exit" in-between the main section of code and the function makes sure that Rexx doesn't accidentally run the code in "CalcEarnings" after it's already used it in the main section.

More to come in the next instalment of this exciting series!