From apple!csg.uwaterloo.ca!giguere Fri Dec 21 12:49:25 1990 Received: by well.sf.ca.us (4.12/4.7) id AA07197; Fri, 21 Dec 90 12:49:16 pst Received: from csg.waterloo.edu by apple.com with SMTP (5.61/25-eef) id AA29898; Fri, 21 Dec 90 12:19:58 -0800 for larryo Received: by csg.uwaterloo.ca id ; Fri, 21 Dec 90 15:19:39 EST From: Eric Giguere Message-Id: <9012212019.AA27703@csg.uwaterloo.ca> Subject: REXX article, part 1 To: well!larryo@apple.com, giguere@csg.uwaterloo.ca (Eric Giguere) Date: Fri, 21 Dec 90 15:19:35 EST X-Mailer: ELM [version 2.3 PL5] Status: RO Hi Larry, this is the main text for the REXX article. Note that there are several messages following this. I'm also sending you all this stuff on an IBM PC diskette via regular mail. Hope you like it. If you need to reach me before January 3, I can be contacted at (403) 465-3208. Otherwise I'll be back at my Kitchener address.... Merry Christmas. Eric ------------------------------ main article ------------------------------ % % rexx.tex -- REXX article for CL % % three sidebars: 1) IBM vs. Microsoft, 2) ANSI standard, 3) UIs % \documentstyle[magazine,example,cprog]{article} \def\emph#1{{\sl #1\/}} \def\keyword#1{{\tt #1}} \def\var#1{{\bf #1}} \def\myexample{\singlespace\begin{example}} \def\endmyexample{\end{example}\doublespace} % % Document begins here... % \begin{document} % % Header stuff... % \address \title{REXX: Not Just A Wonder Dog} % % Main text ... % Programming languages are far from intuitive. A language like C can be downright obscure (\emph{obsfucated} in C parlance), complicated enough to scare off the casual computer user. That's why users are often guided to languages like Pascal and BASIC when they want to learn learn how to program. A cleaner, interpreted language allows the concepts to be understood without being hindered by language constructs. There's one problem with this scenario: it assumes that the user \emph{wants} to learn how to program. What really happens is that the user wants to customize their environment --- put up a menu of all their applications when the computer boots up, for example --- or integrate their applications --- import data from one company's database into another company's word processor. They make inquiries and are told they need to write programs to accomplish these tasks. Suddenly a simple request has evolved into a complicated task. A lot of users simply give up --- either they can't learn to program, or they don't want to program, or else their time is better spent elsewhere. ``What they really need,'' I can hear you saying, ``is a scripting language, like MS-DOS batch files or the Unix C shell.'' A good choice, but scripting languages are just as obscure! And they usually lack the features --- windowing, application integration and extension, perhaps even some useful but ``high-level'' programming constructs --- that users are looking for. What's needed is a cross between a simple scripting language and a high-level programming language. REXX is one such language, and this article will show you why. \section*{History} REXX was developed by Mike Cowlishaw of IBM in the early 1980's. The original REXX interpreter was developed on IBM System/370 mainframes running VM/CMS. Versions were distributed internally in IBM's research laboratories and the language evolved as users requested new features and reported problems. REXX gained enough popularity that IBM adopted it as the official System Product Interpreter for CMS. REXX is still in active use today on System/370 mainframes running a variety of operating systems. REXX has also migrated to other platforms. REXX is currently available for MS-DOS, OS/2 and Unix. IBM includes REXX as the ``Common Program Interface'' for its SAA standard, though they don't refer to it as REXX. OS/2 version 1.3 now includes a REXX interpreter as well, as does the Extended Edition of OS/2 version 1.2. But the most popular micro-based version of REXX, known as ARexx, is available on the Amiga. As proof of this popularity, Commodore now includes ARexx --- a third-party commercial product by a small software developer that gained a large following in the Amiga user community --- with the latest version of the Amiga operating system. REXX is slowly gaining recognition from the computing community at large. The first annual REXX Symposium was held last year at the Stanford Linear Accelerator (SLAC), which runs an environment of IBM mainframes and Amigas integrated with REXX/ARexx. IBM wants to establish REXX as a standard for macro processing and program integration. And most significantly, ANSI has started the standardization procedure for the language. \section*{REXX Features} There are four things that characterize the REXX language and differentiate it from other programming languages. The first is that REXX is an \emph{interpreted} language. REXX programmers benefit from the quick turnaround time that an interpreted language offers. It also makes REXX suitable for those ``quick'n dirty'' once-only programs that can be so useful to a programmer. But to make matters even more interesting, REXX itself includes an \keyword{INTERPRET} keyword that can be used to evaluate an arbitrary expression as a REXX statement. (Note that researchers at IBM have developed a REXX \emph{compiler}, but the compiler lacks some of REXX's more esoteric features, including the \keyword{INTERPRET} keyword. The compiler is used with large REXX programs where increased performance is desired.) The second characteristic is REXX's syntactic flexibility. REXX is a structured programming language that includes the usual control structures found in modern procedural languages. A free-form approach to programming is encouraged by the generous use of white space, comments and optional syntax. Variables do not have to be declared until they are used and their types are context-dependent. REXX's third feature is its built-in debugging facility. The \keyword{TRACE} keyword can be used to trace a REXX program's execution. Interactive tracing resembles the source level debugging capabilities of typical C programming environments. Both CMS REXX and ARexx allow the tracing facilities of running programs to be controlled by external commands. The last --- and perhaps most important --- feature of REXX is its capability to seamlessly interface with one or more ``host'' environments. A REXX program can send commands to a host environment, which can be another program or the underlying operating system. Hosts can invoke REXX programs and exchange data with them, making REXX suitable for use as a general-purpose macro language. The REXX command facility is described in more detail later on. \section*{REXX Examples} It's traditional to start any discussion of a programming language with a ``Hello world'' program: \begin{myexample} /* REXX "Hello world" program */ say "Hello world" say 'Hello' 'world' say "Hello" "worl" || 'd' \end{myexample} REXX programs should always start with a comment, which like C can be multi-line and are delimited by {\tt /*} and {\tt */}. This is not just good programming practice --- the CMS command interpreter uses the comment to differentiate REXX programs from programs written in the EXEC2 scripting language. The example program uses the \keyword{SAY} keyword to print the string ``Hello world'' three different ways. Strings are one of REXX's strong points and can be delimited with either double quotes or apostrophes. Adjacent strings will be concatenated with an intervening space --- the third \keyword{SAY} uses the concatenation operator to join the letter 'd' to 'worl' without an intervening space. Adding variables is simple: \begin{myexample} /* REXX with variables */ say hello Hello = "Hello world" say HELLO hello = 3 say hello * 6 + "2" \end{myexample} This program prints the lines: \begin{myexample} HELLO Hello world 20 \end{myexample} Note that the variable \var{hello} was not actually defined before its first use. A REXX variable (or \emph{symbol}) has its own name (converted to uppercase) as its default value. Variable names are not case-sensitive. The third \keyword{SAY} demonstrates the context-sensitive nature of REXX expression evaluation. Symbol values are always stored as strings. REXX converts these strings to numbers when necessary, generating an error if a string isn't a valid number. REXX includes the usual arithmetic operations such as addition, subtraction, multiplication, division and exponentiation, though the standard REXX function library is somewhat lacking in numeric functions. Because numbers are stored as strings, REXX offers arbitrary-precision arithmetic and automatic conversion between numeric formats. \section*{Clauses and Functions} A REXX program is composed of \emph{clauses}. A clause ends with a semicolon, which is optional if the clause is alone on a line. REXX will also add implied semicolons after a colon (used for labels) and certain keywords, which avoids many syntax errors. The basic REXX clause is the \emph{instruction} clause, which is a clause that starts with a REXX keyword. Instructions are used mostly to control program flow (see below). Another REXX clause is the \emph{assignment} clause, which assigns a value to a symbol. A \emph{label} clause (a symbol and a colon) defines an internal function, while a \emph{null} clause (white space and comments) is ignored completely. An expression not part of an instruction or assignment clause is treated as a \emph{command} clause. REXX evaluates the expression and then passes it off to a command host for further processing. More on this later. Functions come in three forms. The first form is the \emph{internal} function, which is a group of clauses in the REXX program that start with a label clause and end with a \keyword{RETURN} instruction. The second type of function is the \emph{built-in} function, a predefined REXX function. The library of built-in functions is always available to REXX programs and includes an extensive list of string processing and data conversion functions. The third type of function is the \emph{external} function. External functions are programs that are invoked from within a REXX program, and are usually REXX programs themselves. Functions are called within an expression using a syntax similar to C or Pascal: \begin{myexample} smallest = min( 5, 3, -2.5, 90 ) \end{myexample} Functions can also be invoked as procedures using the \keyword{CALL} instruction: \begin{myexample} call myfunc 89, "a string" \end{myexample} Return values, if any, are ignored when functions are called using the second form. Internal functions can inherit the caller's environment or use the \keyword{PROCEDURE} instruction to create their own environment. Variable scoping is dynamic: a function can choose to use its caller's set of variables or to define its own set. If it defines its own set, it can still access some of its parent's symbols using the \keyword{EXPOSE} instruction. \section*{Control Instructions} REXX includes the usual array of control instructions, including if/then/else clauses and a particularly powerful \keyword{DO} loop which includes for/while/until variants: \begin{myexample} /* Print out 1, 3, 5, 7 */ do i = 1 to 10 by 2 until i > 6 say i end \end{myexample} The \keyword{DO} instruction can also be used to group other instructions. The \keyword{INTERPRET} instruction evaluates an expression and then interprets it as if it had been inserted into the REXX program source at that point. Any valid and complete REXX construct is allowed except for label clauses: \begin{myexample} /* Assign 4 to the symbol FRED */ data = 'FRED' interpret data '= 4' \end{myexample} As you can imagine, the \keyword{INTERPRET} instruction is very powerful and sometimes indispensible. \section*{Input and Output} Each REXX program has access to an input stream and an output stream. Data can be retrieved from or placed on the streams using various instructions (\keyword{PULL}, \keyword{PUSH}, \keyword{SAY}) and built-in functions. Most REXX implementations provide file manipulation functions and ways of redirecting the input and output streams, but these methods are system-dependent. REXX also provides a \keyword{PARSE} instruction for parsing data. The instruction: \begin{myexample} /* Get the args */ parse arg first second rest \end{myexample} sets the symbols \var{FIRST} and \var{SECOND} to the first and second words of the argument line passed to a REXX program, setting \var{REST} to the remainder of the line. Much more complex parsing is possible. On CMS it's common to have REXX programs act as front ends for other programs, parsing command-line arguments for the actual program and printing usage information if incorrect options are used. \section*{Commands} The ability to interface with one or more \emph{host environments} is perhaps REXX's most useful feature. A host environment is a program that knows how to invoke and exchange data with REXX programs. The protocols used are system-dependent, but the concepts are similar across all REXX implementations. One simple example of a host environment is the underlying operating system. Most REXX implementations will allow a REXX program to issue file system commands. For example, the following ARexx program uses AmigaDOS commands to delete the contents of my Amiga's RAM drive and then recreate some useful directories: \begin{myexample} /* Clean up my RAM: drive */ address command "delete ram: all" "makedir ram:env ram:t ram:clipboards" \end{myexample} The string that follows the \keyword{ADDRESS} instruction tells REXX which host to send commands; ARexx uses ``command'' to indicate AmigaDOS. Operating system commands can even invoke other programs. Listing 1 shows a simple ARexx program I use to make daily backups of important parts of a software project. It does this by invoking the Zoo file archiver on selected directories. \begin{figure} \begin{myexample} \input{listing1} \end{myexample} \end{figure} Command processing is left completely up to the host environment. REXX simply evaluates the command clause and passes it to the host. The host processes it and sets a return code and an optional result string which the REXX program can use to determine whether a command succeeded or failed. Some REXX implementations allow a host environment to directly set and retrieve the values of REXX variables using the REXX Variable Interface (RVI) facility. While stand-alone REXX programs can be quite useful in and of themselves, the power of REXX really shines through when used as a macro language for applications. It's easy to extend the functionality of an application that supports REXX macros. For example, consider a text editor with REXX support. The editor can provide simple text and cursor manipulation commands for use by REXX macros and a way to invoke a REXX macro from within the editor (usually by menu selection or by pressing a certain key sequence). The user can then write macro programs that manipulate the current file being edited. Listing 2 shows an example of an ARexx macro for the CyngusEd Professional text editor. The macro asks the user to input a string and then deletes all the text from the current cursor location until the input string is found. Three simple operations --- mark block, search for string, cut block --- are combined into one macro. \begin{figure} \begin{myexample} \input{listing2} \end{myexample} \end{figure} REXX command processing is even more useful in a multitasking environment because it can be used to \emph{integrate} two or more applications. For example, this article was written using a text editor and the \TeX{} typesetting system on my Amiga. My text editor, Amiga\TeX{} and the Amiga\TeX{} previewer all run as separate tasks. When I wish to format the current file I'm editing, I just hit a function key to invoke the ARexx macro shown in Listing 3. That macro saves the file to disk and then invokes Amiga\TeX{} with its filename. While Amiga\TeX{} churns away, it brings the previewer up front and displays the pages for me as they are formatted. If an error occurs, the ARexx macro retrieves the location of the error from Amiga\TeX{} and jumps to that location in the text file. A similar setup can be used with a C compiler to quickly locate and correct compilation errors. \singlespace \cprogfile{listing3} \doublespace One big problem with REXX command processing right now is the lack of standards. Each application defines the commands that it will accept, making it impossible to write a macro that will work across a class of applications --- the ARexx macro in Listing 2 will only work with the CygnusEd Professional text editor, for example. The software developer must provide the user with a detailed list of supported commands. Movement is afoot to remedy the situation somewhat by establishing command standards for specific implementations of REXX. Whether or not the ANSI committee chooses to address this issue is up to them. \section*{REXX's Future} This article has only touched on some of the features of the REXX programming language --- we haven't examined \emph{stems}, the REXX equivalent of arrays, for example. The emphasis of the article was on how REXX can be used as a ``power tool'' by even the most casual of programmers. The reference material listed in the bibliography --- Cowlishaw's book in particular --- will provide you with more details on the language itself. REXX is already the dominant macro language in at least two environments (CMS and the Amiga) but whether it gains the same foothold in the IBM PC world is another matter. It's an environment worth exploring, though, and you'll soon come to appreciate the power and expandability it gives you. \section*{References} \singlespace \begin{description} \item[] M. F. Cowlishaw. \emph{The REXX Language: A Practical Approach to Programming}. Prentice-Hall. \item[] C. Daney. ``REXX in Charge''. \emph{BYTE}, August 1990. \item[] S. Gillmor. ``ARexx at Work''. \emph{BYTE}, August 1990. \item[] W. S. Hawes. \emph{ARexx User's Reference Manual}. \item[] Mansfield Software Group. \emph{Personal REXX User's Guide}. \item[] R. P. O'Hara and D. G. Gomberg. \emph{Modern Programming Using REXX}. Prentice-Hall. \item[] N. C. Shammas. ``Personal REXX''. \emph{BYTE}, January 1988. \end{description} \end{document} From apple!csg.uwaterloo.ca!giguere Fri Dec 21 12:49:34 1990 Received: by well.sf.ca.us (4.12/4.7) id AA07261; Fri, 21 Dec 90 12:49:31 pst Received: from csg.waterloo.edu by apple.com with SMTP (5.61/25-eef) id AA00102; Fri, 21 Dec 90 12:20:38 -0800 for larryo Received: by csg.uwaterloo.ca id ; Fri, 21 Dec 90 15:20:23 EST From: Eric Giguere Message-Id: <9012212020.AA27722@csg.uwaterloo.ca> Subject: sidebar 1 To: well!larryo@apple.com, giguere@csg.uwaterloo.ca (Eric Giguere) Date: Fri, 21 Dec 90 15:20:22 EST X-Mailer: ELM [version 2.3 PL5] Status: RO This is the first sidebar for the REXX article. None of the sidebars are necessary to the article, but I thought they might be interesting... ---------------------- start text --------------------------- % % ui.tex -- Sidebar on user interfaces and REXX % \documentstyle[magazine,example,cprog]{article} \def\emph#1{{\sl #1\/}} \def\myexample{\singlespace\begin{example}} \def\endmyexample{\end{example}\doublespace} % % Document begins here... % \begin{document} % % Header stuff... % \title{User Interfaces and REXX} \begin{center} {\bf (sidebar)}\\ \end{center} % % Main text ... % In today's computing environment the graphical user interface (GUI) plays an important part, and this is what REXX lacks the most. REXX is very much a line-oriented language, with no support for windows or menus. There are two approaches to solving this problem. The first approach is to provide a library of windowing routines that users can call to add GUI functionality to their standalone or macro REXX programs. This is the approach taken by Personal REXX, with its text-oriented RXWINDOW function package, and by ARexx, which offers two graphically-oriented windowing libraries, RexxArpLib and Rx\_Intui. These libraries provide functions to open windows, display text, add menu items, and so on. A simple ARexx program, for example, can use the functions in the RexxArpLib to display a list of programs to launch, which the user can choose from by pointing and clicking the mouse --- useful for applications or operations that don't have icons. Another approach is to extend the REXX language to include some useful windowing concepts. This approach is being investigated by researchers at the Computer Systems Group, University of Waterloo. A prototype language has been developed based on REXX that allows declarations of the form: \newpage \begin{myexample} window input_window title "Please Enter Your User ID" text "UserID: #################", userid endwindow input_window \end{myexample} This block of instructions defines an input window. The window is then activated using a special {\tt DOWINDOW} instruction. Similar declarations allow the user to create menus and display file browsers. Although the language is still under development, it's proven to be useful already in the creation of user-friendly software installation programs. And because it's based on REXX, it's simple for users to create and customize their own ``workbench''-type environments. \end{document} From apple!csg.uwaterloo.ca!giguere Fri Dec 21 12:49:42 1990 Received: by well.sf.ca.us (4.12/4.7) id AA07275; Fri, 21 Dec 90 12:49:39 pst Received: from csg.waterloo.edu by apple.com with SMTP (5.61/25-eef) id AA00125; Fri, 21 Dec 90 12:20:56 -0800 for larryo Received: by csg.uwaterloo.ca id ; Fri, 21 Dec 90 15:20:40 EST From: Eric Giguere Message-Id: <9012212020.AA27731@csg.uwaterloo.ca> Subject: sidebar 2 To: well!larryo@apple.com, giguere@csg.uwaterloo.ca (Eric Giguere) Date: Fri, 21 Dec 90 15:20:38 EST X-Mailer: ELM [version 2.3 PL5] Status: RO % % ansi.tex -- Sidebar on ANSI REXX committee % \documentstyle[magazine,example,cprog]{article} \def\emph#1{{\sl #1\/}} % % Document begins here... % \begin{document} % % Header stuff... % \title{ANSI REXX} \begin{center} {\bf (sidebar)}\\ \end{center} % % Main text ... % There's been enough interest in REXX for ANSI to consider creating a standard definition for the language. IBM is spearheading the move to standardize the language with participation from software vendors that support REXX as a general-purpose macro language for integrating applications. The first meeting of the X3J18 committee is slated for January, 1991, and will be over by the time you read this. The committee is aiming for a 1992 date for completion of the standard. (If the ANSI C experience is any indication, the target date is very optimistic.) Also of note is the upcoming REXX Symposium, sponsored by the Stanford Linear Accelerator (SLAC). It will be held in Pacific Grove, California, on May 8 and 9, 1991. \end{document} From apple!csg.uwaterloo.ca!giguere Fri Dec 21 12:49:51 1990 Received: by well.sf.ca.us (4.12/4.7) id AA07289; Fri, 21 Dec 90 12:49:48 pst Received: from csg.waterloo.edu by apple.com with SMTP (5.61/25-eef) id AA00176; Fri, 21 Dec 90 12:21:14 -0800 for larryo Received: by csg.uwaterloo.ca id ; Fri, 21 Dec 90 15:20:58 EST From: Eric Giguere Message-Id: <9012212020.AA27738@csg.uwaterloo.ca> Subject: sidebar 3 (last of 3) To: well!larryo@apple.com, giguere@csg.uwaterloo.ca (Eric Giguere) Date: Fri, 21 Dec 90 15:20:56 EST X-Mailer: ELM [version 2.3 PL5] Status: RO % % ibm.tex -- Sidebar on IBM vs. Microsoft % \documentstyle[magazine,example,cprog]{article} \def\emph#1{{\sl #1\/}} % % Document begins here... % \begin{document} % % Header stuff... % \title{IBM vs. Microsoft} \begin{center} {\bf (sidebar)}\\ \end{center} % % Main text ... % Which language will become the dominant IBM PC macro language? Microsoft is pushing BASIC as its solution, but IBM and other major software vendors are betting their chips on REXX. (``Lotus Makes a Case for REXX To Foil Microsoft's BASIC Plan'', \emph{PC Week}, June 18, 1990.) REXX originated at IBM, and so far it has the lead. REXX comes standard with OS/2 1.3, while the Mansfield Software Group's \emph{Personal REXX} has been available for a number of years on MS-DOS machines (and now OS/2). It doesn't hurt that REXX is dominant on other platforms as well, most notably on the Amiga and on IBM mainframes running VM/CMS. IBM has chosen REXX as the standard procedural language for its Systems Application Architecture (SAA). REXX also has the advantage of built-in support for inter-application communication. Then again, Microsoft pulled a fast one on IBM with the release of Windows 3. It should be an interesting fight. \end{document} From apple!csg.uwaterloo.ca!giguere Fri Dec 21 12:50:01 1990 Received: by well.sf.ca.us (4.12/4.7) id AA07299; Fri, 21 Dec 90 12:49:57 pst Received: from csg.waterloo.edu by apple.com with SMTP (5.61/25-eef) id AA00301; Fri, 21 Dec 90 12:22:11 -0800 for larryo Received: by csg.uwaterloo.ca id ; Fri, 21 Dec 90 15:21:56 EST From: Eric Giguere Message-Id: <9012212021.AA27751@csg.uwaterloo.ca> Subject: Listings To: well!larryo@apple.com, giguere@csg.uwaterloo.ca (Eric Giguere) Date: Fri, 21 Dec 90 15:21:54 EST X-Mailer: ELM [version 2.3 PL5] Status: RO These are the REXX example listings that are included with the article. ----------------------- Listing 1 ------------------------------- /* * Listing 1: save.rexx, a simple ARexx program * that Zoos a project for daily backups. */ /* Set up the directory and file info */ home_dir = "work:rc" backup_dir = "work:rc/backups" /* Create a unique name for the zoo file based on today's date */ name = date( 'sorted' ) || ".zoo" full_name = backup_dir || "/" || name /* Move to the project directory and delete any archive with the same name. */ address command "cd" home_dir "delete >nil:" full_name /* Zoo important parts */ call zooit "src/*.c" call zooit "h/*.h" call zooit "doc/*" call zooit "makefile" exit 0 /* The zooit function just adds the given files to the archive */ zooit: parse arg dir_name "zoo a" full_name dir_name return----------------------- Listing 2 ------------------------------- /* * Listing 2: ARexx macro program for CEDPro. * Asks for a string from the user and deletes * from the current cursor location until the * string is reached. */ options results address 'rexx_ced' "getstring" String = result if (String = "") | (String = "RESULT") then exit 0 "mark block" search for '"'||String||'"' 1 0 1 0 "cut block" exit 0 ----------------------- Listing 3 ------------------------------- /* * Listing 3: An ARexx macro to get the current file * from CEDPro and pass it to AmigaTeX for processing. */ if showlist( "Ports", "AmigaTeX" ) = 0 then exit options failat 5 /* Get filename to process */ address "rexx_ced" "status 21" filename = result if( result = "" | result = "RESULT" )then exit 0 "status 19" /* get pathname */ pathname = result "save" /* make sure we save file */ /* OK, tell AmigaTeX to process it */ address "AmigaTeX" "ToFront" "Activate" call do_abort "TeXify" pathname /* OK, TeX is done, now check the prompt to see if an error occurred */ "NextPrompt" "Prompt" prompt = getclip( "AmigaTeX.Prompt" ) if( prompt ~= "**" )then /* oops! error! */ do "ErrorLoc" error = getclip( "AmigaTeX.ErrorLoc" ) call do_abort address "rexx_ced" "cedtofront" parse var error file line column "jump to file" filename "jump to" line column "okay1" "Error on line" line "at column" column end exit 0 /* This function merely kicks AmigaTeX a few times until it's in a known state */ do_abort: procedure address "AmigaTeX" i = 0 do while RC ~= 0 "NextPrompt" "Abort" if i > 10 then return i = i + 1 end return ---------------------- end of listings --------------------------