If you’ve programmed under IBM operating systems, you’ve undoubtedly heard of Rexx. Rexx is the scripting and command language IBM bundles with all its mainframe, mid-range, and lower-end operating systems. What you might not be aware of is that Rexx also runs on almost every other operating system in the known universe. You can download Rexx free for all versions of Windows®, Linux, UNIX®, BSD, Mac OS, and DOS, and many other systems. It even runs on the three major operating systems for handheld devices: Windows CE, Palm OS, and Symbian/EPOC32.
What this means is, if you learn Rexx, you’ll know a scripting language that runs everywhere from mainframes to handhelds—and everything in between. Rexx is a general-purpose language that's powerful enough for mainframes yet flexible enough for other platforms. Best of all, Rexx is easy to learn.
In this article, I'll give you a quick introduction to Rexx as a basis for using it to access IBM DB2 UDB data. (In a follow-up article, I'll present and discuss more example Rexx scripts that go much further in explaining how to script Rexx specifically for DB2 applications.) I’ll briefly overview what the Rexx language looks like and show you how easy it is to learn. I’ll also describe the many free and open source Rexx interpreters available and tell you where to download them. Most importantly, I’ll direct you to other free sources of information on the Web (see Resources). Within a matter of days, you can learn to program using Rexx, a scripting language that applies to almost any programming problem and runs on almost any machine.
OK—now that you know Rexx is easy to learn, it's time to prove it. Here’s a complete Rexx script:
input = 'invoice_file.txt' /* Name the input file */ do while lines(input) > 0 /* Do while "lines to read" */ input_line = linein(input) /* Read in the next line */ if pos("INVOICE OVERDUE", input_line) > 0 then say "Found it! Here's where:" input_line else say "Not found in this line:" input_line end
This script reads all lines from an input file one at a time and scans them
for the phrase
INVOICE OVERDUE. If it finds
this phrase, the script writes a message and the line in which it was
found. It also displays rejected lines with an appropriate "not found"
In this script, the first line assigns the name of the input file, here
invoice_file.txt, to a variable named
input. This is a simple assignment statement as
is found in almost all programming languages. In Rexx, the character
string or literal assigned to the variable may be enclosed in either
single or double quotation marks:
input = ‘invoice_file.txt’ /* Name the input file */
do while loop that follows drives the
program by processing the input lines from the input file one at a time.
It uses the built-in
lines function to
determine if there are more lines left to read in the input file. The
lines function returns 0 when no more lines are
left to read:
do while lines(input) > 0 /* Do while there are lines to read */
In Rexx, all built-in functions are identified easily because they always
are followed immediately by parentheses that contain their input
argument(s). There can be no space between the left parenthesis and the
function it follows. The previous statement shows that the lines function
takes one argument, which is the name of the file it should test for "end
of file." Remember that in our script, the variable input refers to the
input file named
Now here’s the heart of the program. This line uses Rexx’s
pos built-in function to determine whether the
input line contains the character string
if pos("INVOICE OVERDUE", input_line) > 0 then
pos function returns the position at which
INVOICE OVERDUE occurs within the
given line. Or, it returns 0 if the phrase is not found in the line.
The test in this statement enables the script to write a line to the
display screen that tells whether the character string
INVOICE OVERDUE exists in the input line.
say instruction then writes the output
line. In our example, the
say instruction has
two operands. The first is a character string literal, enclosed in quote
marks, and the second is the variable that contains the line from the
say instruction can take as many
operands as you like, and it concatenates them together automatically and
sends them to the user’s display screen:
if pos("INVOICE OVERDUE", input_line) > 0 then say "Found it! Here’s where:" input_line else say "Not found in this line:" input_line
That’s it. You’ve read a complete Rexx script. You can see that, as languages go, Rexx requires very little in the way of syntax and has no "special characters." Is this what makes it an easy language?
Why Rexx is easy
The simple script I've shown demonstrates Rexx’s ease of use. For example, it shows that you do not have to declare or predefine program variables. Simply encode a new variable whenever and wherever you want, and Rexx defines it for you. For example, the first line in the program defined the variable input automatically by virtue of assigning it a value; it was not necessary to declare or predefine this variable prior to using it.
Nor is it necessary to declare the data type of a variable. All variables in Rexx are typeless. Rather, they contain variable-length strings and their contents define their data type. If you assign a variable a string that looks like a numeric value, Rexx will allow you to perform calculations on it. If you assign a variable a character string, Rexx will allow you to perform string manipulation operations on it (such as parsing, pattern-matching, or concatenation). Where some languages require you to predefine variables and assign them "data types," Rexx defines variables dynamically by their contents and use. Rexx transparently converts data as necessary when called for by various operations, and it automates much of the detail work that absorbs programmers using other languages.
Here is a simple example:
a = 3 /* Create a numeric variable */ b = "4" /* This string value also represents a number */ say a + b /* Displays the numeric result: 7 */ say a || b /* Concatenate the two strings together… */ /* Displays: 34 */ c = "Hi!" /* Create variable that is a character string */ say a + c /* This results in error! You can not */ /* add a character value to a number */ -> SYNTAX: Bad arithmetic conversion (error 41)
This code first creates two variables containing values representing numbers. (A number in Rexx is any string of digits, which optionally can contain a decimal place or be preceded by a sign. Numbers also can also be expressed exponentially in scientific or engineering notations.) The third statement shows how the two numbers can be added together, and the fourth statement shows they also can be treated as character strings consisting of a single digit each. The fourth statement concatenates or pastes together the two character strings—which happen to consist of digits—by the concatenation operator ||. The last two lines show that, while Rexx performs conversions automatically whenever possible, it will not let you add a non-numeric character string to a number; only variables that contain numeric values can be treated as numbers in calculations.
Let’s get back to our original example: the script that scans for the
INVOICE OVERDUE. Note that this script
does not open its input file. Files are much like variables in that you do
not have to define them explicitly prior to their use—you simply start
reading or writing the file. Similarly, the program does not have to close
the file after use as this is done automatically when the program
terminates. I also didn’t end the script formally (you can code a Rexx
exit instruction to end Rexx code if you like, but it’s not necessary
Beyond the implicit actions it takes on your behalf, Rexx is easy because it is a free-format language. You can use spacing, blank lines, and indentation however you feel most comfortable. As a simple example, you could have written the if statement like this and achieved the same result:
if pos("INVOICE OVERDUE", input_line) > 0 then say "Found it! Here’s where:" input_line else say "Not found in this line:" input_line
Rexx is as forgiving in terms of formatting as a programming language can
be. It also is not case-sensitive. Its instructions, functions, and
variables can be encoded in uppercase, lowercase, or mixed case. For
example, you could have coded the variable name
Input_line; it’s all the same to Rexx. Here’s
yet another way to code the if statement that uses case to distinguish
Rexx instructions and functions from the statement's other elements:
IF POS("INVOICE OVERDUE", Input_Line) > 0
THEN SAY "Found it! Here’s where:" Input_Line
ELSE SAY "Not found in this line:" Input_Line
Why Rexx is powerful
Beyond its ease-of-use, Rexx’s basic design makes it a powerful language. As Figure 1 shows, Rexx consists of a small core of approximately 20 instructions. This core is then surrounded by a rich function set of about 70 built-in functions. This makes it easy to learn the basics while adding to your knowledge of the functions over time. It also means power. Beyond the built-in functions, Rexx scripts easily access dozens of free external function libraries, tools, and interfaces. These handle every imaginable interface, including database access, graphical user interfaces, XML, Web server programming, graphics, MIDI interfaces, Windows Registry updates, speech synthesis, and Apache programming—you name it, and Rexx can access it. You also can check out a few Web sites where you can access these free tools (see Resources).
Figure 1. The elements of Rexx
Much of Rexx’s power comes from the fact that it is a "glue" language. Rexx scripts easily issue operating system commands. Consequently, IBM selected Rexx as its "command procedures language" years ago for its mainframes and other operating systems. Rexx glues together existing code—whether this code comes in the form of operating system commands, interface APIs, services, widgets, objects, functions, interfaces, or tools—and leverages it for greater productivity. This is what makes scripting languages such as Rexx so much more powerful than traditional, compiled programming languages such as C++, C, COBOL, or Java™. Although these languages can issue operating system commands and use generic interfaces with some effort, a scripting language such as Rexx is designed specifically to do just that.
One of Rexx’s most powerful features is its implementation of arrays (sometimes named tables in other programming languages). What makes arrays so powerful is that, not only can they be indexed by numeric subscripts, but you also can subscript them by character strings. Thus arrays support what is sometimes referred to as content-addressable memory or associative memory. This makes Rexx arrays a feature whose power extends far beyond the way tables are used in programming languages that support only numeric subscripting. For example, arrays can support dictionary look-up and form the basis for sophisticated kinds of data structures, such as key-value pairs, linked lists, doubly-linked lists, and trees. Arrays are a generic vehicle to associate variables and values in whatever way makes the most sense to the program, so they are more properly referred to as compound variables. Space forbids us from exploring this intriguing subject here, but you can find more information at the end of this article (see Resources).
Next, I'll briefly describe a few of Rexx’s other features. The language
includes a complete set of instructions for the control of program logic
It supports structured programming and modularity, which are
principles widely accepted as best practices for program design. But Rexx
is a power language and includes instructions for unstructured logic for
those rare cases where you might need them. These instructions include
do forever, and
signal (which is roughly analogous to
goto in other languages).
I’ve mentioned that Rexx contains some 70 built-in functions. These group into the categories of string manipulation, bit manipulation, numeric, input/output, conversion, environmental, and miscellaneous. Rexx scripts invoke external functions in the same manner as built-in or user-written functions (once access is established to the external function library). So when using an external or add-in function library, your Rexx code refers to those functions in the same way it would if they were a built-in feature of the language.
Like most interpreters, Rexx supports interactive debugging. You can run a script, stop it at any time, inspect its variables, and even re-run or alter the code. Rexx’s built-in debugger makes it easy to identify and fix logic errors. Interactive debugging generally is seen as superior to batch-mode debugging (though Rexx supports this, too).
Rexx also includes an exception or error handler. This traps a number of common error conditions (such as syntax errors or arithmetic overflow) and diverts the flow of control to a special error-handling routine you’ve written. The exception trapping provides a standard way to manage common errors from a single routine.
Rexx also supports a communication mechanism named the external data queue, but more typically is called simply the stack. A unique and powerful Rexx feature, the stack provides a vehicle for communication between Rexx routines or programs. Depending on the host operating system and the Rexx interpreter, the stack supports communications between different programs on the same machine or even between different programs on different machines. This includes remote communication across the Internet. Of course, Rexx scripts can also employ more traditional communications vehicles such as TCP/IP, FTP, sockets, and pipes.
Finally, I should mention the portability of Rexx scripts. Rexx has a strong language standard to which all the interpreters mentioned in this article conform. This not only makes your Rexx skills transferable, but it also renders scripts portable. Take a standard Rexx script, and you can port it easily across Linux, Windows, mainframes, handhelds—whatever you like. If your scripts issue operating system–specific commands, Rexx offers several free cross-platform interfaces to buffer scripts from this platform dependency.
Download free Rexx
I’ve mentioned that Rexx comes bundled with all IBM operating systems. In addition, you can download free or open source Rexx for any other operating system. There are eight free or open source Rexx interpreters. Each interpreter meets the Rexx standards, so your Rexx skills apply to all of them and your Rexx scripts will run under any of them. Where the interpreters differ is in the platforms they support and the "extras" they provide. For example, some interpreters run on handhelds, others offer operating –system–specific language extensions, and others support fully object-oriented programming.
Here’s a quick profile of six of the free Rexx interpreters:
|Regina||All major operating systems||The most popular free Rexx interpreter. Its large user community means ample support, and it works with all free tools and interfaces. It comes with many extra built-in functions and excellent, professional documentation. I recommend starting with Regina if you are new to Rexx.|
|Rexx/imc||Linux, UNIX, BSD||This is a UNIX- and Linux-oriented interpreter that includes extensions for these environments. It has a proven track record for long-term support.|
|BRexx||Linux, UNIX, Windows CE, Mac OS, 16- and 32- bit DOS, others||This extremely fast interpreter has a small footprint and runs on many platforms, including resource-limited systems such as Windows CE, embedded Linuxes, and DOS. It offers many extra functions and interfaces and has a long-term track record of support.|
|Reginald||Windows||Reginald customizes and extends Rexx for Windows programmers. It is easy to use and includes many Windows tools such as a GUI, speech, MIDI, and media functions. Reginald provides a standard language alternative to proprietary tools such as VBScript, and it is nicely documented with examples.|
|r4||Windows||r4 extends Rexx for Windows with many tools including a GUI forms tool, color text file viewer and editor, more than 135 Windows command tools, visual accessories, XML to HTML auto-converter, GUI widgets, and others. It also includes excellent tutorials and example scripts.|
|Rexx for Palm OS||Palm OS||This interpreter glues Palm OS applications and databases together via scripts that run without leaving the current application. These scripts can access all Palm data and resources, including TCP/IP, infrared, USB and serial communications, console, clipboard, and others. It runs natively, and it includes good example scripts with easy-to-follow tutorials.|
In addition to these standard, procedural Rexx interpreters, there are also two object-oriented Rexx interpreters. These are fully object-oriented languages with complete and powerful class libraries. They support all OOP principles, including class hierarchies, inheritance, multiple inheritance, encapsulation, abstraction, and polymorphism. Both products are true supersets of standard, procedural Rexx, so you can start programming with them immediately using standard Rexx features and functions, then tip-toe into the object-oriented features at a rate with which you feel comfortable. In addition, your standard Rexx scripts will run under them with no alteration:
|Open Object Rexx||Windows, Linux, UNIX||This is a fully object-oriented superset of classic Rexx. Developed by IBM, it became open source in late 2004. Now enhanced and maintained by the Rexx Language Association, it is the most widely used object-oriented Rexx interpreter.|
|roo!||Windows||roo! also is a fully object-oriented superset of classic Rexx. From the same company as the standard r4 Rexx interpreter, it comes with the same extensive set of Windows tools. It also includes quick, easy tutorials that bridge the gap between standard and object-oriented Rexx programming.|
Lastly, I'll mention that there is even a Rexx for the Java environment, NetRexx. Of all the Rexx interpreters I've discussed in this article, this is the only one that does not meet the Rexx language standards—so it is perhaps best described as "Rexx-like." Its purpose is to bring Rexx’s ease of use to the Java environment. NetRexx scripts use Java classes, and they can create classes used by Java scripts. NetRexx lets you write applets, applications, and servlets without tangling with Java’s C-heritage syntax. You can even use it to create Java Beans and generate fully-commented Java code. NetRexx supports both client- and server-side scripting and runs on any Java Virtual Machine (JVM).
In my next article, I’ll get more technical about Rexx programming and provide some practical coding examples. These example scripts will demonstrate how you can use Rexx as a vehicle for quickly developing programs that access DB2 UDB data. Beyond teaching more about Rexx scripting, they are practical database examples in their own right. I’ll employ the Regina Rexx interpreter, accessing DB2 UDB on a Windows server for the example scripts. But both Rexx and the database interface I’ll use are portable across Linux, UNIX, and other operating systems.
The great thing about working with an open source language such as Rexx is there are so many free and readily available resources to learn more about it (see Resources).
The open source / free software movement is one of the great technology stories of our era. The other big trend today is scripting. Rexx stands at the intersection of these two trends. It offers a free, easy-to-use, powerful, standardized, and universal scripting language. With it, you can quickly program solutions to a wide variety of problems at very low cost. Happy scripting!
- The Rexx Language Association is an independent, non-profit organizaiton dedicated to promoting the use and understanding of the Rexx programming language.
- Kilowatt Software's Classic Rexx Tutorial is a free introductory tutorial to the Rexx programming language.
- Ian Collier's Rexx Tutorial is another classic Rexx tutorial.
- Rexx Programmer's Reference is a comprensive book on Rexx.
- The Rexx Language is the original Rexx definition from 1990.
- Review example Rexx scripts.
- More resources are available at the IBM REXX Family page.
Get products and technologies
- Download free Rexx software for Windows, Reginald Rexx plus Windows tools
- Download more free Rexx tools, Regina Rexx plus tools.
- Windows Rexx Forum
- Mainframe Rexx forum
- English Rexx forum
- French-language forum
- German-language Rexx forum