In this installment of the alt.lang.jre series, I'll pay homage to NetRexx, a language that may well be king when it comes to simple application creation, text processing, and business calculations. Like the previous languages in this series, many of NetRexx's strengths are drawn from its predecessor. REXX, or Restructured Extended Executor, was originally conceived by IBM Fellow Mike Cowlishaw as a general-purpose end-user programming language (see Resources). Developed in the early 1980s, REXX is considered to a precursor to scripting languages such as Tcl and Python. NetRexx is a Java-based dialect of REXX that combines the ease-of-use of a scripting language with the portability and efficiency of the Java platform. Because it is based on REXX, NetRexx is one of the most mature, stable, and reliable of the alternate languages for the JRE.
In this introduction to NetRexx, I'll focus on its easy-to-learn syntax, concise coding, natural text and numeric processing, and complete integration with the Java classes and APIs, and set you on the path to incorporating these features into your development on the Java platform. I'll start with an overview of NetRexx's history and attributes and then use a number of working examples to illustrate its core strengths.
NetRexx's progenitor, REXX, was one of the first programming languages conceived as a scripting (alternately extension, macro, or glue) language. Unlike production languages such as C++ or the Java language, which are compiled, scripting languages tend to be interpreted. NetRexx offers the best of both worlds because it can be directly interpreted or pre-compiled and run independently from its source.
Like Microsoft's Visual Basic, NetRexx's simple, English-like syntax and intuitive semantics make it an accessible language for end user programming. This simplicity combined with the power and stability of the Java platform makes NetRexx an ideal alternative for rapid application development. And it can be easily adopted by existing REXX programmers and entry-level programmers alike.
NetRexx is more concise than the Java language. According to the NetRexx home page (see Resources), the source for a typical Java class has about 35 percent more tokens and requires about 20 percent more keystrokes than that of an equivalent NetRexx class. NetRexx provides exceptional support for text processing programs. In addition to its many Java string and text support features, NetRexx features numerous convenient, built-in string-manipulation functions. Because NetRexx is fully object-oriented and modularized it is an excellent language for developing large-scale applications. Because it is compiled, NetRexx is is efficient to run. NetRexx normally uses is own string data types for calculations, but for increased performance NetRexx can do all computation using Java-native numeric types.
Because its progenitor was originally intended for the creation of mainframe command scripts, NetRexx is an excellent language for scripting processes. It supports many procedural programming constructs and convenience features such as minimal structural overhead (that is, "classless" coding) and little or no need to declare variable types.
The whole point of NetRexx is to let you create applications and applets for the Java environment faster and more easily than you could writing Java code. Like REXX, NetRexx was designed with the following objectives in mind:
- Readability
- Natural data typing and decimal arithmetic
- Emphasis on symbolic manipulation
- Minimal need to declare types
- Platform independence
- Adaptability
- Manageability (keeping the language small and compact)
- No defined size or shape limits
Using Java classes is especially easy in NetRexx, because its classes
and Java classes are entirely equivalent. NetRexx uses the same object
model as the Java language does, so NetRexx can use any Java class and
vice versa, and you can compile or interpret them as needed. NetRexx
also runs everywhere a JRE is supported, so you can access all the Java
classes and APIs from NetRexx and also use the NetRexx runtime (the
netrexx.lang package including its enhanced string type
Rexx) from Java code.
As for how this works, NetRexx is first translated to Java source then automatically compiled to class files. The generated Java code is available for inspection and debugging, although debugging is rarely necessary. The NetRexx compiler script also supports immediate execution of compiled programs, making the experience of developing with NetRexx very similar to that of working with a scripting language.
In fact, NetRexx very nicely combines some of the best features of a production language and a scripting language. Its syntax closely follows REXX's English-like line-oriented and (optional) case-insensitive syntax while fully supporting the structured and object-oriented programming styles more familiar to Java programmers. Some of the unique features of NetRexx as compared to the Java language are as follows:
- Little need to pre-declare variables
- Strings are the basic data type (that is, numbers are represented in
string format)
- String operations are extensive and easily accessed (for example,
in NetRexxx
x = yis the same asx.equalsIgnoreCase(y)in the Java language) - All
Rexxstrings can also act likejava.lang.Mapinstances - NetRexx uses natural indefinite precision decimal values
- Adapter classes automatically provide default Java interface
implementations
- Indirect properties automatically provide getter and setter
methods
- No need to use the
newoperator - Unqualified constants (like Java 5.0's
import static) - Open (that is, classless and
mainless) code - Automatic generation of tracing code reduces the use of
System.out.printlns - Automatic imports of many commonly used
java.packages. - Default arguments on methods
- Parameterless functions do not need the parenthesis, thus a typical field get method can resemble a field reference
So far NetRexx sounds like a solid alternative to the Java language
on the Java platform, but not much different from some of the newer
languages such as Jython, JRuby, and Groovy. So what makes NetRexx king?
Well, first off, unlike scripting languages such as Jython and Groovy,
NetRexx's variables are typed, which means that a NetRexx
variable can be any Java language base or object type or the NetRexx
Rexx enhanced string type.
Variables are typed on first assignment based on the source
expression type and function parameters are optionally typed. This
allows for compile-time type checking as well as performance
optimizations. When using NetRexx without interaction with Java code
almost all variables (and expressions) will be of the Rexx
type. NetRexx can perform arithmetic on these strings if they represent
numbers. NetRexx supports indefinite precision values such as the Java language
BigDecimal type (although NetRexx's are far easier to use);
in fact, the Rexx type is the model for the JSR 13 Decimal
Arithmetic Enhancement added in Java 5.0.
Another outstanding advantage of NetRexx is the fact that it can be compiled, which means that syntax and type errors can be detected at compile time and not at runtime. Interpreted, dynamically typed languages such as Jython and Groovy are more flexible than NetRexx in some cases, but can also be less reliable. Runtime type-checking means that a certain percentage of errors normally found by a compiler go undetected until execution, and some are never detected. As a result, many software engineering theorists believe that compilation and static typing is a prerequisite for success in large scale engineering efforts.
In addition to typed variables, NetRexx offers the Rexx
data type. Rexx is a string type that can be used in
arithmetic and also as a keyed map or indexed (optionally sparse) array.
The Rexx type supports typical string and numeric
operations and is easily converted to/from a Java
java.lang.String. Note that in Rexx string
functions the first character is in position one, not zero.
Table 1 summarizes some of the operators of the Rexx
data type, giving you a good overview of the structural utility of
NetRexx.
Table 1. Summary of the Rexx data type operators
| Syntax | Description | Example(s) |
= \= <> ><
|
Equal or Not Equal Strict Equal or Not Equal |
"abc" = "ABC" returns 1"abc" == "ABC" returns 01 \= 2 returns 1
|
> < >= \< <= \>
|
Relational comparison Strict relational comparison |
"abc" < "xyz" returns 1"abc" = "abc " returns 1"abc" << "abc " returns 1
|
& | && \
| Logical operations |
0 & 1 returns 0 \1 returns 0
|
+ - * / % // **
| Arithmetic operators |
1 + 2 returns 3; 2 ** 3 returns 8"1" + "2" returns 3 (actually "3")
|
|| (blank) (abuttal)
| Concatenation |
a = "123"; b="456";a||b returns "123456"a b returns "123 456"a"pqr"b returns "123pqr456"1 || 2 returns "12"
|
Table 2 summarizes the Rexx data type methods.
Table 2. Summary of the Rexx data type methods
| Syntax | Description | Example(s) |
string.abbrev(info[,length])
| Returns 1 if info is a prefix of string |
"abcdef".abbrev("xyz") returns 0
|
string.abs, string.min, string.max, string.sign
| Gets absolute, minimum, maximum and sign of string value |
-1.abs returns 1 1.max(2) returns 2
|
string.b2x, string.c2d, string.c2x, string.d2x, string.d2x([pad]), string.x2b, string.x2c, string.x2d([pad])
| Converts to/from binary(b), character(c), decimal(d), or hexadecimal(x) |
100.d2x(4) returns "0064"
|
string.center(length[,pad]), string.left(...), string.right(...)
| Pads string with blank or pad character to length |
"abc".center(9) returns " abc "
|
string.changestr(old,new)
| Replaces old with new in string |
"1234567".changestr("345", "abc") returns "12abc67"
|
string.compare(target[,pad])
| Compares padded strings yielding -1, 0, 1 |
"12345".compare("12346") returns -1
|
string.copies(n)
| Repeats string |
"*".repeat(10) returns "**********"
|
string.countstr(pattern)
| Counts occurrences of pattern in string |
"10100100".count("1") returns 3
|
string.datatype(option)
| Determines the type of the string; Tests for numeric type or case |
"1234".datatype("N") returns 1
|
string.delstr(n[,length]), string.delword(...)
| Removes length (or rest of string) characters or words from string at position n |
"12345678".delstr(2,4) returns "1678" "now is the time".delword(2,2) returns "now time"
|
string.exists(index)
| Sees if index exists in string |
x[1] = 1; x[2] = 2; x[3] = 3 returns 1
|
string.format([before[,after[,places[,digits[,form]]]]])
| Formats a numeric string |
13.467.format(2,2,3) returns "01.35E+001"
|
string.insert(new[,n[,length[,pad]]]), string.overlay(...)
| Inserts or overlays new into string at position n |
"1234".insert("abcd",3,2) returns "12ab34" "1234".overlay("abcd",3,2) returns "12ab"
|
string.length
| Gets string length |
"1234".length returns 4
|
string.lower([n[,length]]), string.upper(...)
| Converts case |
"ABCdefg".lower(3,2).upper(5,2) returns "ABbcDEfg"
|
string.pos(target[,n])
| Finds target in string; 0 if not found |
"1234".pos("23") returns 2
|
string.reverse
| Reverses the string |
"1234".reverse returns "4321"
|
string.sequence(final)
| Gets the sequence of character between string and final (both must be 1-character strings) |
"0".sequence("9") returns "0123456789"
|
string.space([n[,pad]])
| Splits words in string with n pad characters between them |
"one two three".space(3) returns
"one two three"
|
string.strip([option[,char]])
|
Removes leading("L"), trailing("T"), or both("B" – default) occurrences of char (default spaces)
|
" 12345 ".strip returns "12345"
|
string.substr(n[,length[,pad]]), string.subword(...)
| Extracts a substring of characters or words string at n for length with optional padding |
"123".substr(2,4,"*") returns "23**" "now is the time".subword(2,2) returns "is the"
|
string.translate(out,in[,pad])
| Translates the string using the in and out tables |
12345.translate( "qwertyuiop", "1234567890") returns "qwerty"
|
string.trunc([n])
| Truncates the numeric string |
123.456.trunc(2) returns 123.45 123.456.trunc returns 123
|
string.verify(ref[option[start]])
| Determines if any character in ref is in/not in string starting at start. Option is "Match" or "Nomatch" (default); else 0 |
"123abc4567".verify("1234567890") returns 4
|
string.word(n)
| Gets the nth word of string |
"Now is the time".word(2) returns "is"
|
string.wordindex(n), string.wordlength(n)
| Gets the index or length of the nth word |
"Now is the time".wordindex(2) returns 5 "Now is the time".wordlength(2) returns 2
|
string.wordpos(phrase[,start])
| Gets the word number of the first word of phrase |
"Now is the time".wordpos("is the") returns 2
|
string.words()
| Gets the number of words in string |
"Now is the time".words returns 4
|
And finally, NetRexx provides the statement types summarized in Table 3.
Table 3. Summary of NetRexx statement types
| Statement | Description | Example(s) |
| Package | Defines the package for this code. |
package com.ibm.example
|
| Import | Imports other class or package definitions. When the package name ends with a dot (.) any child package is automatically imported. |
import java.
import javax.
|
| Assignment | Any expression, assigned to a target. |
x = 100
name = last', 'first
|
| No op | No operation. |
nop
|
| Say | Prints an expression. |
say 'My name is' name
|
| Options | Sets compile and/or execution options. |
options strictcase
|
| Trace | Automatically writes tracing code. |
trace methods
|
| Numeric Control | Sets options on number processing. |
numeric digits 100
|
| Exit | Stops execution. |
exit 1
|
| Parse | Parses a string into parts based on a simple pattern. Often simpler to use than regular expressions. |
proto = "x=func(1,3)"
parse proto -
result'='name'('arg1','arg2')'
|
|
If If/Else | One- or two-way conditional processing. |
if name = 'Barry' then return
if x < 0 then x = -x
if x > 0 then fac = factorial(x)
else say 'Bad argument' x
|
| Select |
N-way conditional processing. May also have exceptions and protection like the do statement.
|
select
when x > 3 then say "It's > 3"
when z = 2 then say "z=2"
otherwise say "It's bad!"
end
|
| Blocks | A statement group;Blocks may be labeled for use by continue or iterate. |
do ...;... end
do label topLoop
:
end
|
| Exception Blocks | A statement group with optional exception support. |
do
x = 1 + value
catch e = NumberFormatException
e.printStackTrace
finally
x = 2
end
|
| Synchronized Blocks | A statement group with optional synchronization support. |
do protect anObject
anObject.wait
end
|
| Looping |
Repeated blocks. May have an iteration, while and/or until clause. Iteration may be forever,
over a value, or over the keys in a Rexx variable. May also have exceptions and protection like the do statement.
|
loop i=1 to 100 while valid(i)
say "Iteration" i
end
loop key over names
say key"="names[key]
end
|
| Leave a loop | Exits a loop. |
leave topLoop
|
| Continue a loop | Advances to the next iteration of a loop. |
iterate
|
| Return | Returns with an optional expression. |
return x * 10
return
|
| Signal Exception | Generates an exception. |
signal IllegalArgumentException('Bad argument')
|
| Class | Introduces a class. May have all the Java language modifiers but some with different names. |
class MyClass abstract
|
| Properties | Introduces a set of similar properties. May have all the Java language modifiers but some with different names. |
properties private
|
| Method | Introduces a method. Optional parameters are supported. May have all the Java modifiers but some with different names. |
method name(arg1, arg2="") public
|
Tables 1 through 3 offered the structural utility of NetRexx. What remains is to see for yourself how easy and convenient coding with NetRexx can be. We'll start with the quintessential example Hello World! program shown in Listing 1:
Listing 1. NetRexx's Hello World!
say "Hello World!" |
In NetRexx, source files use the extension nrx. The "Hello World" statement is a complete program when placed in a source file such as hello.nrx.
For comparison, take a look at the equivalent Java program, seen here in a file such as hello.java:
Listing 2. Hello World! in Java code
public class hello {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
|
The NetRexx form is clearly much simpler. The nice thing about
NetRexx, of course, is that its code can be directly interpreted or it
can be translated to Java source and automatically compiled to class
files. You can compile the hello program by using the following command:
C:\>java -cp <netrexxc.jar-install-path> COM.ibm.netrexx.process.NetRexxC hello |
Or, assuming the correct CLASSPATH is set, you can use the following convenient NetRexxC script:
C:\>netrexxc hello |
You could then run the program by using this command:
C:\>java -cp <hello.class-path>;<netrexxr.jar-install-path> hello |
Or, for more convenient processing you could use the following command, which compiles and runs the program:
netrexxc -run hello |
For the ultimate in convenience you could use the following command, which does not compile the NetRexx program but instead directly interprets it:
C:\>netrexxc -exec -nojava hello |
Convenience is one thing and results are another. In the next several sections, I'll use some more realistic examples to give you a glimpse of what NetRexx is capable of. Listing 3 shows a complete NetRexx program:
Listing 3. Command-line argument processing
loop i = 1 to arg.words
say 'Argument' i'='arg.word(i)
end
|
Listing 3 nicely illustrates several features of NetRexx. Each line
is a statement. Command-line arguments are accessed via the built-in
name arg, which is a string consisting of blank separated
"words." Access to the words is achieved through the word
built-in function, and the number of words is accessed via the words
built-in function.
Looping is done via the loop/end statement
group. The say statement demonstrates abuttal string
concatenation. Unlike the Java language, NetRexx often presents no need
for a plus (+) operator between string terms.
The caching factorial calculator shown in Listing 4 lets you see NetRexx-style class definition in action:
Listing 4. The caching factorial calculator
class Factorial -- A factorial calculator
properties private
value -- the value to get the factorial of
properties static
seen = '' -- cache of prior calculated values
method Factorial(v) -- constructor
value = v
method compute -- calculate the result
select -- determine case
when value < 0 then -- bad arg!
signal IllegalArgumentException('arg < 0')
when value < 2 then -- base case
return 1
otherwise -- need to calculate
if \seen.exists(value) then -- not done before?
-- calculate this value and cache it
seen[value] = value * Factorial(value - 1).compute
return seen[value] -- get value from the cache
end
|
For being relatively concise, Listing 4 lets you see a number of NetRexx's key features. For example, you can see that remarks are introduced by a sequence of two adjacent hyphens (--) and, other than for assignments, statements are introduced by keywords. Class and method bodies are not enclosed in delimiters but are instead introduced by dividing header statements. (The indentation shown is optional but it improves readability.)
You also likely noted that classes are introduced by the
class statement. Properties (Java fields) are
introduced by the properties statement. As expected, the
method statement introduces methods. And multi-way conditional
tests are done via the select statement.
All properties with the same nature (for example,
private) can be grouped under one properties
statement. Variables such as value or seen
are "declared" by assignment. REXX variables such as seen can act as a
map and values are looked up and/or set via indexing (no need to use get
or put methods). The variable's value is used for undefined keys.
Instances are created by calling the appropriate constructor
function, so no new operator is required. Methods are
invoked (as in the Java language) with the dot (.) operator. Parameterless
methods can be (conveniently) declared and invoked without the use of
parentheses. This makes getter methods look like property references.
The bottom-line observation is that NetRexx supports all the
functions of the Java language but sometimes with different syntax. For
example, the NetRexx signal statement is the same as
the Java language's
throw statement. NetRexx does not allow inner (that is,
nested) classes, but it creates the same effect by supporting multiple
classes per source file and declaring a class as a
dependent minor class of another parent class, thus
allowing the dependent class to access the state of the parent class.
And to think, I'm not yet done showing you the power of NetRexx!
The sorting routine in Listing 5 is another example of more complex NetRexx coding:
Listing 5. A sort method
-- sort an array of strings; 0 <= low <= high < items.length
method sort(items=Rexx[]) static
sortInPlace(items, 0, items.length - 1)
method sortInPlace(items=Rexx[], low, high) static inheritable
if low < high then -- have a range to sort
do
reorder = (low + high) % 2 -- pick a value to reorder
swap(items, low, reorder) -- reorder an element
lastLow = low
loop i = low + 1 to high
if items[i] < items[low] then
do; lastLow = lastLow + 1; swap(items, i, lastLow); end
end
swap(items, low, lastLow)
sortInPlace(items, low, lastLow - 1) -- sort left
sortInPlace(items, lastLow + 1, high) -- sort right
end
-- swap two elements
method swap(items=Rexx[], x=int, y=int) static binary inheritable
t = items[x]
items[x] = items[y]
items[y] = t
|
Again, many key NetRexx features are illustrated in the above example.
Multiple statements can be entered on one line if separated by
semicolons (;). Methods do not need to be in any class (in this case
the file name is automatically used as the class name). Variables can be
assigned types, for example Rexx[]. The Rexx
string type is the implied type of all untyped variables. And, although not
shown, a default value expression can follow the type.
Attributes such as static can be specified. NetRexx
supports all the Java language modifiers but sometimes with different names. For
example, inheritable is the equivalent of
protected in the Java language.
The binary attribute instructs the NetRexx compiler to
use native Java types and arithmetic (versus the default Rexx
type character mode arithmetic). This can increase performance at the
cost of some flexibility.
I'll end this introduction to NetRexx with a program that creates a GUI. As you consider the simple AWT-based application, you'll see firsthand NetRexx's ability to be called from Java code and to access all the features of the Java platform.
The GUI shown in Listing 6 is a Java Applet subclass called
Scribble:
Listing 6. Class Scribble: A Java applet
/* Scribble.nrx: the 'Scribble' applet, using an Adapter class */
class Scribble adapter binary extends Applet -
implements MouseListener, MouseMotionListener, ActionListener
last_x=int; last_y=int -- these record mouse coordinates
method init
addMouseListener(this) -- we want mouse events
addMouseMotionListener(this) -- and mouse movements
b=Button("Clear") -- make a button
b.addActionListener(this) -- get it's events
add(b) -- add the button to the applet
method mousePressed(m=MouseEvent)
last_x=m.getX; last_y=m.getY -- get mouse coordinates
method mouseDragged(m=MouseEvent)
g=this.getGraphics -- get applet's Graphics context
x=m.getX; y=m.getY -- get mouse coordinates
g.setColor(Color.black)
g.drawLine(last_x, last_y, x, y) -- draw new line segment
last_x=x; last_y=y -- save coordinates
method actionPerformed(a=ActionEvent) -- Button pressed
g=this.getGraphics
g.setColor(this.getBackground) -- clear
g.fillRect(0, 0, getSize.width, getSize.height)
|
This applet can be launched from a Web page such as the one shown in Listing 7:
Listing 7. Web page to launch the Scribble applet
<html>
<head>
<title>IBM NetRexx applet example</title>>
</head>
<body>
: *** other HTML content ***
<applet code="Scribble.class" width=400 height=400>
Your browser does not support applets.
</applet>
: *** other HTML content ***
</body>
</html>
|
*Listings 6 and 7 are included from the NetRexx home page.
One thing to notice about the above examples is the lack of import
statements. The following packages (and their subpackages) are imported
by default: java.lang, java.io,
java.util, java.net, java.awt,
java.applet, and netrexx.lang.
Like the Java language, NetRexx supports multi-line comments with the pattern /*
... */. Source-lines can be continued by ending them with a single hyphen (-).
In this code example there is no properties statement; the default is
private properties. Although not shown in this example,
NetRexx can automatically generate get and/or set methods for
properties.
The NetRexx adapter attribute causes any unimplemented
method of any implemented interface to be automatically coded as an empty
method. The needed java.awt.Applet methods are overridden.
The types of most of the local variables are automatically set to the
Rexx type. As in the Java language, this is a reference to the
object running the method. Finally, notice the complete integration of the Java
AWT APIs and how easy they are to use from NetRexx.
Figure 1 shows the Scribble GUI in use.
Figure 1. Sample Scribble GUI
To paraphrase NetRexx inventor Mike Cowlishaw, NetRexx is a programming language derived from both REXX and the Java language: its rules of syntax closely follow those of REXX while its semantics are closer to those of the Java language. NetRexx is a REXX dialect that can be as efficient and portable as the Java language. Like REXX, NetRexx is designed to allow clear separation of its concepts, so it may be introduced gradually. Also like REXX, sensible defaults are defined to aid ease of learning and use but they can be turned off for the programmer who needs advanced features.
In this sixth installment in the alt.lang.jre series, I've introduced you to the key programming features of NetRexx, including a comprehensive overview of its statement and data types. I've used realistic examples to demonstrate some of the benefits of NetRexx programming on the Java platform, including an easy-to-learn syntax, concise coding, easier to use and more natural text and numeric processing, and complete integration with the Java classes and APIs.
Each of the languages profiled in this series brings some unique features to programming on the Java platform. Typed variables and compiled code are the standout features that differentiate NetRexx from languages such as Jython and Groovy. NetRexx is also based on one of the oldest of the scripting languages, REXX, which ensures it is quite stable and has been well tested by the user community.
All in all, NetRexx is a simple, efficient programming language that is especially well suited to large-scale development projects on the Java platform. Although not demonstrated in this article, it is also very easy to create server-side code such as servlets and EJB components in NetRexx, because it compiles to standard Java class files. See Resources to learn more about REXX, NetRexx, and other articles in this series.
| Name | Size | Download method |
|---|---|---|
| j-alj12074-source.zip | HTTP |
Information about download methods
- The source for this article includes the complete code for the
FactorialandSortingclasses. Click the Code icon at the top or bottom of the article to access the source files. - The IBM developer kits page offers the all the latest ports for the Java platform from IBM. You can also download the most current version of the JDK from java.sun.com.
- Don't miss a single article in this series! Visit the alt.lang.jre series page for a complete listing of previous articles.
- IBM hosts many excellent resources for learning more about NetRexx. Start with
the following:
- The IBM Redbook Creating Java
applications using NetRexx is an excellent introduction to NetRexx
and a guide to many of its practical application.
- See also the IBM Redbook VM/ESA Network Computing with Java and NetRexx.
- The IBM NetRexx home page is a starting point for learning about the language, checking out its documentation, and downloading the REXX-to-NetRexx converter, among other tools.
- The IBM Redbook Creating Java
applications using NetRexx is an excellent introduction to NetRexx
and a guide to many of its practical application.
- Visit the IBM
REXX family home page to learn more about NetRexx's powerful
progenitor, and see the REXX
home page for more information about using REXX.
- David Mertz's "Rexx
for everyone" (developerWorks, February 2004) suggests that
REXX occupies an important niche between shell scripting and full
systems languages. The article includes a good historical overview and
some discussion about NetRexx.
- You'll find articles about every aspect of Java programming in
the developerWorks Java technology
zone.
- Browse for books on these and other technical topics.

Dr. Barry Feigenbaum is a member of the IBM Worldwide Accessibility Center, where he serves as a member of a team that helps IBM make its products accessible to people with disabilities. Dr. Feigenbaum has published several books and articles, holds several patents, and has spoken at industry conferences such as JavaOne. He serves as an Adjunct Assistant Professor of Computer Science at the University of Texas, Austin.





