Rexx Programming "Rules of Thumb"

by Howard Fosdick - 2005, 2006


Rexx is one of the most flexible, capable programming languages around.   Its range of options and power means that some
stylistic "rules of thumb" can be helpful.   This list offers some.

The list includes "common errors" as well.  Remember them to reduce your debugging time and write error-free code.

This material is extracted and abbreviated from the book Rexx Programmer's Reference.  The book provides fuller
explanations and examples of the rules briefly listed here.

Optimal "rules of thumb" can vary somewhat according to whether you're writing a short script or a large programming
system.   I note rules of thumb that are specially recommended practices for large systems.   They are collected towards
the bottom of the list.

If you have any "rules of thumb" to contribute to this list, please send them to the webmaster for this site (webmasterA
at the domain of  I will attribute them to you.  Thank you!

Rexx Rules of Thumb--

Write Readable Code, Not "Fortune-Cookie" Code

Some programmers like to write clever, "fortune-cookie" code.  Their code doesn't live long because it can not be
maintained.  Strive to write the most readable, maintainable code, not the shortest or most clever code.  This first
rule is the basis for many that follow.

Capitalize on Capitalization

            Take advantage of Rexx's case-insensitive nature to make code more readable.

Use Good Variable Names

Since you can use long variable names, do so for readability.  Include embedded underscores in names too --

            Good   ->   Social_Security_Number

            Poor    ->   sno

Use Spacing and Indentation

Take advantage of Rexx's free-format nature.  Indent according to the nesting level of IF and DO statements.  Line up
ENDs as appropriate.

Code whose horizontal alignment matches its logic is much easier to read and maintain.

Limit Expression Nesting

You can nest expressions to any depth, but readability is better served by breaking up nested expressions into separate
lines of code.  Ever had to maintain someone else's highly-nested expressions?  It's very difficult.

Comment Code

Rexx's free-form comments allow you to comment your code wherever and however you like.   Well-commented code is way
easier to maintain than code without explanation.

Maintain Code Comments

When you maintain code, you must update the code comments also.  Otherwise they will become misleading rather than an

Handle Errors

            Good code is robust and fail-safe.   Handle all errors from—

·         Command results

·         Interpreter-raised error conditions

·         Return codes from interfaces

·         I/O results

Use Rexx's Built-in Error and Exception Handling to Manage Errors

While there are some cases where you will not want out-of-line error handling, you should normally employ Rexx's
built-in exception handlers.

Check All Return Codes

            Good programs check all return codes to ensure their robustness and viability.

Explicitly Initialize Subscripts

            Explicitly initialize a subscript at the top of the DO loop at which it is used.

Do Not Alter Subscripts Inside Loops

Do not explicitly alter a subscript variable while within a loop.   Let the DO instruction increment it for you

Use Top-Driven Loops Only

Use only top-driven DO loops.  Bottom-driven loops do not conform to the rules of structured programming.

Don't Exit From Inside a Loop

Do not early force-exit from within a DO loop.  Structured programming only allows for normal exit at the loop's
top-driven condition check.

Use a Loop Subscript Only for a Loop

If you use a variable like I for subscripting a DO loop, do not also use it to index a table from within that loop!

If You Nest Loops, Use a Different Subscript for Each

If you don't follow this principle, your logic won't work properly.  When nesting DO loops, you've got to use a
different subscript for each DO.

Build OS Commands in Simple Steps

Build strings that represent operating system commands in several simple steps, not in a single huge, complicated

Build OS Commands in a Variable

Build strings that represent operating system commands within a variable.  You can then display the variable to ensure
the command string is properly created.

Avoid Unnecessary Quotation Marks in Building OS Commands

One sometimes sees double-quoting when building operating system commands for mainframe environments.  This is not
necessary and hurts the readability of the code.   Use as few quotes as possible when concatenating command strings.

Use Rexx-Aware Editors

            Using a Rexx-aware editor can reduce your error rate.  Example products include:

        * THE (The Hessling Editor) for Windows, Linux, Unix, etc.

        * The REXX Text Editor (RexxEd), distributed with Reginald for Windows

        * The Interactive System Productivity Facility (ISPF) on mainframes

        * XEDIT on mainframes

Publish Site Style Standards

This renders code at a site similar regardless of the author.  Consider what your enforcement mechanism should be.

Use Automated Tools to Ensure Standards Compliance

Many sites buy or develop tools to ensure standards compliance and the similarity of code across authors.  Templates
that programmers fill out for documentation purposes are one good example.

Consider Code Reviews

Code reviews are another technique to ensure common code style and conformance to site standards.

Don't Forget to End a Comment

Every comment must be ended by */.    Otherwise your program becomes one long comment!

Don't Forget to End a Literal String or Parenthetical Expression

            Same as ending a comment… you must do it!

Don't Forget RETURN or EXIT

Remember that functions must return a string to the caller; subroutines may optionally do so.  Be sure to code RETURNs
and EXITs where required.

Don't Overlook Automatic Upper-case Conversion

Remember that instructions like PULL and ARG auto-convert to upper-case.   If you do not want auto-conversion, use PARSE

This can be especially important if your program reads in file names.   File names are case-sensitive in Linux and Unix,
but not in Windows.

Left Parentheses Must Immediately Follow Functions

Don't forget to immediately follow a function by a left parenthesis.  No intervening space is allowed.

                        Incorrect    ->   rc =  function_name    (argument1)

                        Correct       ->   rc =  function_name(argument1)

CALLs Do Not Use Parentheses

            Remember that CALL statements do not use parentheses to enclose arguments.

                        Incorrect     ->   call  subroutine(argument1, argument2)

                        Correct        ->   call  subroutine  argument1,  argument2

Don't Forget that Functions Return Strings

            Don't forget that a function returns a string.  You must provide a place for the string to go.

                        Incorrect   ->   function_name(argument1)

                        Correct      ->   feedback = function_name(argument1)

                        Correct      ->   call   function_name  argument1

Watch Statement Continuations

Remember that the comma is Rexx's line continuation character.   Surround comma's used for statement continuation with
blanks for readability.  Line them up if multiple ones occur across several lines.

Use Strict Comparisons When Required

If you want to compare a string including its preceding or following blanks, be sure to use Rexx's strict comparison

Don't Strict-Compare Numbers

            Strict comparisons are for strings, not for numeric values.

Don't Use DO UNTIL

Structured programming doesn't permit bottom-driven loops.  Any such loop can be structured properly by using the
DO-WHILE instead.

Don't Use SIGNAL as a GOTO

Structured programming does not allow GO TO's.  Use structured control constructs instead (DO, IF, etc).   Set a control
flag if necessary to convert your GO TO's to IF's and DO's.

How to Return More than One Value from a Function

Rexx functions return a single value only.  If you want to return more than one value you can:

        * Concatenate the values into one returnable string, then use PARSE in the caller to get the individual values

        * Write values to a file, which you use as a global passing mechanism

How to Iterate Over all Tails in a Stem Variable

This is not part of ANSI-standard classic Rexx.   But many Rexx interpreters have this built-in as an extra (for
example, Open Object Rexx, roo!, Reginald, and BRexx).  Or you can use any of several add-on packages that support this
(for example, REXXUTIL).

Leverage Rexx's Interactive Trace Facility

The big advantage to interpreters is interactive debugging.  Leverage Rexx's built-in debugging facilities to greatly
reduce your debugging time.

Maintain a Site-wide Function or Object Library

Code re-use can only happen if you put the proper mechanisms in place to facilitate and encourage it.

Consistency is the Mother of All Virtues  -- especially for large programs!

Whatever coding style you pick, apply it consistently.   Consistency may be the "hob-gobblin of small minds," but in
coding it is a key virtue.  If you've ever had to read and maintain a large set of programs written by someone else,
you'll know what I mean.

Write Structured Code                -- especially for large programs!

Structured programming has been established for over twenty years ago as a superior programming methodology, especially
for large programs.  Use it if you wish to write maintainable code.

Write Modular Code                -- especially for large programs!

Modular principles complement structured programming principles.  Both have long been proven superior coding techniques.
If you don't believe me, you might read Yourdon and Constantine.

Declare All Variables                      -- especially for large programs!

Not declaring variables is easy and convenient for small scripts.  But declare all variables for larger systems!
Otherwise you'll likely experience errors based on uninitialized variables.  Use the NOVALUE built-in exception handler
to trap any variable that has not been properly assigned a value.

Don't Use Global Variables            -- especially for large programs!

Programmers often use global variables because they're easier than passing arguments.  But for large programs, the most
common maintenance errors are due to global variables.  I recommend you not use global variables, especially on larger
projects.   Sometimes a configuration or ini file works well for storing global variables, or even a single routine that
is effectively a just memory definition or "control block" definition.