Jump to content

Rexx

From Alfawiki
Rexx
Company typeProgramming language
IndustrySoftware development
Founded1981
FounderMike Cowlishaw
ProductsProgramming language, interpreters, compilers

Rexx (an acronym for restructured extended executor) is a high-level programming language created by Mike Cowlishaw at IBM. It is available in both proprietary and open-source interpreters across a wide range of computing platforms, with compiler options provided for IBM mainframe computer systems. Rexx is utilized for scripting, developing application macros, and general application development. As a versatile scripting language, it is recognized as an early influence on languages such as Tcl and Python.

This language is embedded within several operating systems, functioning as the primary scripting tool for platforms like OS/2, MVS, VM, and AmigaOS. Additionally, it facilitates macro support in programs including SPF/PC, KEDIT, THE, and ZOC. When paired with an appropriate engine, Rexx enables scripting capabilities in applications that utilize the Windows Scripting Host ActiveX engine, such as VBScript and JScript. It is included with VM/SP Release 3+, TSO/E Version 2+, OS/2 (starting from version 1.3 as Procedures Language/2), AmigaOS 2+, PC DOS 7.0/2000, ArcaOS, and Windows NT 4.0 (Resource Kit: Regina). During the late 1980s, Rexx was adopted as the standard scripting language for the IBM Systems Application Architecture, at which point it was renamed "SAA Procedure Language REXX".

Within mainframe contexts, Rexx scripts or commands are commonly referred to as EXEC, a term derived from the file types used in earlier CMS EXEC and EXEC 2 scripts, as well as Rexx scripts running on VM/SP R3 through z/VM. Execution of scripts is managed by indicating the Rexx interpreter on the initial line via comments or file path directives (EXTPROC). On MVS systems, Rexx scripts are identified either by dataset qualifiers or through comments containing the keyword "REXX". OS/2 employs the ".cmd" extension, which it shares with other scripting languages; here, the interpreter is specified on the first line. In Linux environments, Rexx scripts generally start with a shebang line. Application-specific file extensions are used for Rexx macros.

Name

Initially named REX (short for Reformed Executor), an additional "X" was appended to distinguish it from other products. The language's name appeared in all uppercase letters due to restrictions in mainframe coding environments. Early publications by Mike Cowlishaw referred to it as REXX in uppercase, though cover designs sometimes displayed mixed case. The expansion REstructured eXtended eXecutor was adopted for the system product released in 1984. This article uses the mixed-case form Rexx, which is more common in professional settings.

Attributes

Rexx offers several features significant to business applications:

  • A straightforward syntax paired with a concise instruction set of 23 commands
  • Capability to dispatch commands across diverse environments
  • Support for functions, procedures, and commands tailored to specific environments
  • An integrated stack that interoperates with host system stacks
  • Free-form and case-insensitive syntax that improves readability and user-friendliness
  • Dynamic typing without the need for declarations or reserved keywords outside local scope
  • Support for arbitrary-precision decimal and floating-point calculations
  • Extensive built-in functions emphasizing string manipulation and word processing
  • Automatic memory management coupled with safeguards against crashes
  • Use of content-addressable data structures and associative arrays
  • Easy access to system commands and resources
  • Simplified error handling mechanisms alongside built-in tracing and debugging tools
  • Minimal restrictions and streamlined input/output capabilities

The language's simplicity—highlighted by its use of a single data type (character string)—facilitates rapid application development and simplifies debugging. Its syntax draws inspiration from PL/I but eliminates much of its complexity, adhering to the design philosophy known as the principle of least astonishment, which aims to reduce unexpected behaviors for users.

Certain functionalities like Unix-style command-line argument handling, terminal control features, and inclusion of external libraries are either only partially implemented or available exclusively in select versions of Rexx.

Before 1990

Between March 1979 and mid-1982, Mike Cowlishaw independently created the Rexx language along with an interpreter written in assembly language, aiming to replace the EXEC and EXEC 2 languages. His goal was to design Rexx as a more straightforward and accessible alternative to PL/I, though it exhibits notable distinctions from PL/I.

Rexx was introduced publicly for the first time at the SHARE 56 conference held in Houston, Texas, in 1981. The strong interest expressed by users, particularly Ted Johnston from SLAC, motivated IBM to officially release it as a product in 1982.

IBM incorporated Rexx into a wide range of its operating systems, including VM/CMS, MVS TSO/E, IBM OS/400, VSE/ESA, MUSIC/SP, AIX, PC DOS, and OS/2. Additionally, versions were developed for platforms such as Novell NetWare, Windows, Java, and Linux.

The initial non-IBM version was created for PC DOS by Charles Daney during 1984/85 and distributed by Mansfield Software Group, established by Kevin J. Kearney in 1986. The first Rexx compiler appeared in 1987 for CMS, developed by Lundin and Woodruff. Over time, Rexx versions have been produced for numerous systems including Atari, AmigaOS, various flavors of Unix, Solaris, DEC platforms, Windows CE, Pocket PC, Palm OS, QNX, OS/2, BeOS, Symbian, AtheOS, OpenVMS, Apple Macintosh, and Mac OS X.

ARexx, a Rexx interpreter bundled with AmigaOS from version 2 onward, gained popularity for scripting and automating application control. Many Amiga programs feature "ARexx ports," allowing users to automate workflows across different applications through Rexx scripts.

From 1990 Onwards

In 1990, Cathie Dager from SLAC organized the inaugural independent Rexx symposium, which led to the establishment of the Rexx Language Association; this organization has continued to hold annual conferences since then.

By 1992, two significant open-source Rexx implementations emerged: Ian Collier’s REXX/imc tailored for Unix systems and Anders Christensen’s Regina (later maintained by Mark Hessling), supporting both Windows and Unix platforms. CERN nuclear physicist Vasilis N Vlachoudis developed BRexx, a compact implementation compatible with multiple operating systems such as Unix, Linux, BSD variants, macOS, Windows, and even Android. BRexx/370 is specifically designed for IBM mainframe environments.

Within OS/2 environments, Watcom provided the visual development tool VX-REXX while Hockware offered VisPro REXX. Portable Rexx from Kilowatt and Personal Rexx by Quercus targeted DOS systems with support for Windows command prompt integration. Since the mid-1990s, two prominent Rexx derivatives have appeared:

  • NetRexx: This variant compiles into Java bytecode through Java source code; it does not use reserved keywords and adopts Java’s object-oriented model, making it largely incompatible with traditional Rexx syntax.
  • Object REXX: An object-oriented evolution of Rexx that maintains substantial backward compatibility.

In 1996, the ANSI standard X3.274–1996 was published to formalize Rexx specifications. Since 1985, more than twenty-five books covering Rexx have been released.

Rexx marked its 25th anniversary on March 20, 2004, during the 15th International Symposium hosted by the Rexx Language Association in Böblingen, Germany.

On October 12, 2004, IBM announced intentions to distribute their Object REXX implementation under the Common Public License. Recent Object REXX versions include an ActiveX Windows Scripting Host (WSH) engine that enables scripting within Microsoft Windows environments.

The initial public release of Open Object Rexx (ooRexx) occurred on February 22, 2005. ooRexx features a WSH scripting engine that facilitates programming for Windows operating systems and applications in a manner comparable to other scripting languages such as Visual Basic, JScript, Perl, Tcl, and Python.

According to the TIOBE index in January 2018, Rexx ranked at number 30; however, since then it has frequently dropped below the top 50 or even outside the top 100 rankings.

The Rexx Language Association Symposium held in 2019 celebrated four decades of Rexx development. This event took place in Hursley, England—the original location where Rexx was designed and implemented.

Toolkits

  • RexxUtil – a collection of functions for handling files, directories, windowed input/output, and system services such as WAIT and POST – is accessible in most Rexx environments.
  • Rexx/Tk – a graphical toolkit for Rexx applications, comparable to Tcl/Tk – enjoys broad availability.
  • RexxEd – an integrated development environment (IDE) tailored for Rexx – was created specifically for Windows.
  • RxSock facilitates network communications; various add-ons and Regina Rexx implementations are also available. Many Windows resource kits include a Rexx interpreter for the Windows command line, which is compatible with DOS.

Host environment

A Rexx host environment refers to a designated interface that directs commands to applications, operating systems, or subsystems. The interpreter keeps track of recognized environments in a list, with the first entry being the default environment. By employing the ADDRESS statement, a Rexx script can switch the default environment or send a single command to a chosen environment without changing the default setting.

Instruction types

Rexx categorizes instructions into three types:

  • Assignments – single statements such as symbol=expression assign values; for instance, count=count+1 increments the variable "count".
  • Keyword instructions – begin with a keyword; for example, say "Message" outputs the text 'Message'.
  • Commands – expressions evaluated by the interpreter and forwarded as commands to the default environment; for example, "sleep 10" instructs a Unix-like host to pause execution for ten seconds.

Address instruction

The address instruction serves three distinct purposes:

  • When used without operands, it swaps the first two host environments, generally restoring the previous default.
  • When provided with only an environment name, it promotes that environment to the front of the list, making it the new default.
  • When given both an environment and an expression, it sends the evaluated expression as a command to the specified environment.

The ANSI standard introduced options that allow redirection of command input and output.

Do groups

do groups control program flow by:

  • Grouping multiple instructions inside if or select blocks.
  • Managing loops with repetitor and conditional clauses that terminate upon meeting specified conditions.

A do group begins with do and concludes with end. In ooRexx and NetRexx, there is a subtle distinction between do and loop: a plain do is equivalent to do 1, while loop implies an endless loop.

Loops can be prematurely exited using iterate, and entire groups can be terminated using leave.

Simple do

Commonly used within conditional statements: <syntaxhighlight lang=rexx> if foo=bar then

 do
   i=1;j=3
 end

else

 do
   i=2;j=4
 end

</syntaxhighlight>

Conditional loop

Allows testing conditions either before or after executing loop instructions:

do while [condition]
  [instructions]
end
do until [condition]
  [instructions]
end

Basic repetitive loop

Performs a set of instructions a specified number of times:

do expression
  [instructions]
end

Loops with controlled iteration

Loops can modify variables within defined boundaries:

do index=start [to limit] [by increment] [for count]
  [instructions]
end

If the increment is not specified, it defaults to 1; in the absence of an upper limit, loops continue indefinitely unless halted by conditions or a leave statement.

Infinite loop

Enables continuous looping until externally interrupted:

do forever
  [instructions]
end

Hybrid loops

Repetitive constructs and conditional expressions can be integrated within a single loop, for example:<syntaxhighlight lang=rexx>do i=1 while i<=3; say i; end</syntaxhighlight>

do index=start [to limit] [by increment] [for count] [while condition]

 [instructions]

end

do expression [until condition]

 [instructions]

end

Conditional execution

Conditional logic utilizes if, then, and else blocks enclosed by do and end.

if [condition] then

 do
 [instructions]
 end

else

 do
 [instructions]
 end

For single statements, the do and end keywords may be omitted.

if [condition] then

 [instruction]

else

 [instruction]

Branching on multiple conditions

The select statement manages branching based on multiple conditions, inspired by PL/I's SELECT;. Unlike the switch construct in C or Java, Rexx's when clauses evaluate complete conditions, effectively acting as a series of cascading if-then-else checks.

select

 when [condition] then
   [instruction or nop]
 when [condition] then
   do
   [instructions or nop]
   end
 otherwise
   [instructions or nop]

end

The nop command is mandatory if no action follows a when. An optional otherwise clause handles cases where no conditions are met; omitting it results in a syntax error if no matches occur.

Typeless nature

Variables have no fixed type and initially evaluate to their uppercase identifier. Their data type depends on how they are used:

<syntaxhighlight lang="rexx"> say hello /* outputs HELLO */ hello = 25 say hello /* outputs 25 */ hello = "say 5 + 3" say hello /* outputs say 5 + 3 */ interpret hello /* outputs 8 */ drop hello say hello /* outputs HELLO */ </syntaxhighlight>

Variable evaluation

If no novalue handler is set, undefined variables return their uppercase names. The built-in function SYMBOL returns "VAR" for existing variables without triggering the novalue. The function VALUE retrieves variable contents without activating the novalue, primarily used for accessing and modifying environment variables, analogous to POSIX's getenv and putenv.

Compound variable

The language incorporates compound variables, which extend a base variable (known as the stem) by appending fields (called tails) to form complex data structures such as lists, arrays, multi-dimensional arrays, trees, and records.

Rather than relying on specialized numeric indexing for arrays, compound variables utilize numeric tails to provide similar capabilities.

Example: <syntaxhighlight lang="rexx"> do i = 1 to 10

 stem.i = 10 - i

end </syntaxhighlight> Tails are not limited to integers; for example: <syntaxhighlight lang="rexx"> i = 'Monday' stem.i = 2 </syntaxhighlight> A default value can be set for a stem without specifying a tail: <syntaxhighlight lang="rexx"> stem. = 'Unknown' stem.1 = 'USA' stem.44 = 'UK' stem.33 = 'France' </syntaxhighlight> In this case, accessing stem.3 yields the default value 'Unknown'.

To remove all elements from a stem, use: <syntaxhighlight lang="rexx"> drop stem. </syntaxhighlight> It is common practice to use stem.0 as a counter for the number of items stored in a stem. This is particularly helpful in procedures like appending words to a list: <syntaxhighlight lang="rexx"> add_word: procedure expose dictionary.

 parse arg w
 n = dictionary.0 + 1
 dictionary.n = w
 dictionary.0 = n

return </syntaxhighlight> Compound variables can also have multiple tails, enabling structures such as multi-dimensional arrays: <syntaxhighlight lang="rexx"> m = 'July' d = 15 y = 2005 day.y.m.d = 'Friday' </syntaxhighlight> Comparable constructs appear in other languages—for instance, associative arrays in AWK, hashes in Perl and Java, or dynamic objects in JavaScript. Traditional Rexx does not provide native iteration over tails; thus, additional mechanisms are necessary. For example, to count word frequencies: <syntaxhighlight lang="rexx"> add_word: procedure expose count. word_list

 parse arg w .
 count.w = count.w + 1 /* assume count. initialized to 0 */
 if count.w = 1 then word_list = word_list w

return </syntaxhighlight> An example of iterating later: <syntaxhighlight lang="rexx"> do i = 1 to words(word_list)

 w = word(word_list,i)
 say w count.w

end </syntaxhighlight> Newer Rexx versions like Object REXX and ooRexx include built-in support for direct iteration over stems: <syntaxhighlight lang="rexx"> do i over stem.

 say i '-->' stem.i

end </syntaxhighlight>

Parse

The parse statement processes strings following this syntax:

parse [upper] origin [template]

Including the upper keyword converts the input string to uppercase prior to parsing.

The origin parameter identifies the input source:

  • arg – command line parameters
  • linein – standard input (such as keyboard input)
  • pull – Rexx data queue or standard input stream
  • source – program execution context information
  • value expression with – an expression terminated by the keyword with
  • var – a variable reference
  • version – version or release identifier

The template consists of variables interspersed with literal or column delimiters.

Examples

Parsing with variables as template: <syntaxhighlight lang="rexx"> myVar = "John Smith" parse var myVar firstName lastName say "First name is:" firstName say "Last name is:" lastName </syntaxhighlight> Output: <syntaxhighlight lang="output"> First name is: John Last name is: Smith </syntaxhighlight> Using fixed-width column delimiters: <syntaxhighlight lang="rexx"> myVar = "(202) 123-1234" parse var MyVar 2 AreaCode 5 7 SubNumber say "Area code is:" AreaCode say "Subscriber number is:" SubNumber </syntaxhighlight> Output: <syntaxhighlight lang="output"> Area code is: 202 Subscriber number is: 123-1234 </syntaxhighlight>

Interpret

The interpret command executes its argument as Rexx code during runtime, allowing for flexible and dynamic code execution. This feature is useful for scenarios such as passing functions as arguments, performing arbitrary precision calculations, and creating programmatic parsing templates. For instance: <syntaxhighlight lang="rexx"> X = 'square' interpret 'say' X || '(4) ; exit' SQUARE: return arg(1)**2 </syntaxhighlight> This code outputs 16 before terminating the program.

The Valour software took advantage of Rexx's interpretive functionality to develop an OOP framework. Moreover, a never-released Westinghouse product named Time Machine employed this capability to enable complete recovery following critical failures.

Numeric

<syntaxhighlight lang="rexx"> say digits() fuzz() form() /* => 9 0 SCIENTIFIC */ say 999999999+1 /* => 1.000000000E+9 */ numeric digits 10 /* constrained by memory */ say 999999999+1 /* => 1000000000 */

say 0.9999999999=1 /* => 0 (false) */ numeric fuzz 3 say 0.99999999=1 /* => 1 (true) */ say 0.99999999==1 /* => 0 (false) */

say 100*123456789 /* => 1.23456789E+10 */ numeric form engineering say 100*123456789 /* => 12.34567890E+9 */

say 53 // 7 /* => 4 (modulus)*/ </syntaxhighlight>

Example: computing √2 with high accuracy using Newton's iterative method: <syntaxhighlight lang="rexx"> numeric digits 50 n=2; r=1 do forever

 rr=(n/r+r)/2  
 if r=rr then leave  
 r=rr  

end say "SqRt" n "=" r </syntaxhighlight>

Example output:

Calculating the constant e with high precision: <syntaxhighlight lang="rexx"> numeric digits 50 e=2.5; f=0.5 do n=3

 f=f/n  
 ee=e+f  
 if e=ee then leave  
 e=ee  

end say "e =" e </syntaxhighlight>

Example output:

Error handling

The signal instruction allows the runtime environment to respond with custom routines when certain system events arise. These events include:

  • error – Positive return codes from system commands
  • failure – Negative return codes (such as command not found)
  • halt – Unexpected termination of execution
  • novalue – Accessing undefined variables
  • notready – I/O errors, for example reading beyond file end
  • syntax – Program syntax errors or related issues
  • lostdigits – Loss of significant digits (specific to ANSI Rexx)

For example, the following snippet displays a message when the user halts the program: <syntaxhighlight lang="rexx"> signal on halt; do a = 1

 say a  
 do 100000 /* delay loop */   
 end   

end halt: say "The program was stopped by the user" exit </syntaxhighlight>

Starting with Rexx version 4, signal handlers can be assigned names. In this sample, the handler ChangeCodePage.Trap manages a syntax event: <syntaxhighlight lang="rexx"> ChangeCodePage: procedure

 signal on syntax name ChangeCodePage.Trap   

return SysQueryProcessCodePage()

ChangeCodePage.Trap: return 1004 </syntaxhighlight>

Information about handled events can be retrieved using RC, which holds the last error code, and SIGL, indicating the line number where the event occurred.

See also

Further reading

  • Callaway, Merrill. The ARexx Cookbook: A Tutorial Guide to the ARexx Language on the Commodore Amiga Personal Computer. Whitestone, 1992. ISBN 978-0963277305.
  • Callaway, Merrill. The Rexx Cookbook: A Tutorial Guide to the Rexx Language in OS/2 & Warp on the IBM Personal Computer. Whitestone, 1995. ISBN 0-9632773-4-0.
  • Cowlishaw, Michael. The Rexx Language: A Practical Approach to Programming. Prentice Hall, 1990. ISBN 0-13-780651-5.
  • Cowlishaw, Michael. The NetRexx Language. Prentice Hall, 1997. ISBN 0-13-806332-X.
  • Daney, Charles. Programming in REXX. McGraw-Hill, TX, 1990. ISBN 0-07-015305-1.
  • Ender, Tom. Object-Oriented Programming With Rexx. John Wiley & Sons, 1997. ISBN 0-471-11844-3.
  • Fosdick, Howard. Rexx Programmer's Reference. Rexx Language Association, Apex, NC, 2025. ISBN 9789403745527.
  • Gargiulo, Gabriel. REXX with OS/2, TSO, & CMS Features. MVS Training, 1999 (3rd ed. 2004). ISBN 1-892559-03-X.
  • Goldberg, Gabriel and Smith, Philip H. The Rexx Handbook. McGraw-Hill, TX, 1992. ISBN 0-07-023682-8.
  • Goran, Richard K. REXX Reference Summary Handbook. CFS Nevada, Inc.,1997. ISBN 0-9639854-3-4.
  • IBM Redbooks. Implementing Rexx Support in Sdsf. Vervante, 2007. ISBN 0-7384-8914-X.
  • Kiesel, Peter C. Rexx: Advanced Techniques for Programmers. McGraw-Hill, TX, 1992. ISBN 0-07-034600-3.
  • Marco, Lou ISPF/REXX Development for Experienced Programmers. CBM Books, 1995. ISBN 1-878956-50-7.
  • O'Hara, Robert P., Gomberg, David Roos. Modern Programming Using Rexx. Prentice Hall, 1988. ISBN 0-13-597329-5.
  • Rudd, Anthony S. Practical Usage of TSO REXX. CreateSpace, 2012. ISBN 978-1475097559.
  • Schindler, William. Down to Earth Rexx. Perfect Niche Software, 2000. ISBN 0-9677590-0-5.


External links