NetRexx -- easier Java programming


This is part 2 of a 3-part article by Michael F. Cowlishaw, the creator of the REXX language.  This article was first published in the "Java Report", June 1997 (pp 45-48).

Repeated is the last paragraph of the first installment, re-published in the Sep '98 issue of the RexxLA newsletter.

This class, entered in a file called Rainbow.nrx, can be compiled by the NetRexx compiler.  The resulting Rainbow.class is then used exactly like an applet compiled from Java.  Here, briefly, are some things to note about this example:

  1. The first line is an optional 'block comment'.  NetRexx block comments may be nested.  Line comments are also allowed, introduced by '--'.
  2. There is a minimum of punctuation and special notations; this makes the language easier to learn (and to remember, if writing programs infrequently).  For instance, you can use semicolons to separate multiple statements on one line, but they are not necessary when      there is only one statement on a line.  The usual English notation of a trailing hyphen is used to indicate continuation.
  3. The language is case-insensitive.  Although the method used from the Color class is called 'getHSBColor', it can be successfully called using the name 'getHSBcolor'. Strict case-sensitivity is available, if preferred, as a compiler option.
  4. When a method call takes no arguments (for instance 'size', in the example), the pair of 'empty' parentheses is optional.
  5. The 'core' Java class packages (java.lang, java.io, java.net, java.util, java.awt, and java.applet) are imported automatically.
  6. The only explicit use of a type is in the argument to the paint method; all others are inferred from context.  Type checking, however, is not compromised; a variable is permitted only a single type, set at its first use.  There's only one notation for specifying types, which is used for both declarations and conversions (casts).
  7. Each method is ended by the start of the next method or class (or by the end of the source file).  Class and instance variables are placed before the first method in a class.
  8. In this example, all calculations are done in ANSI Rexx decimal arithmetic, performed by methods in the NetRexx string class, called 'Rexx'.  Automatic conversions (which are only allowed if there is no significant loss of information) convert these numbers to the types expected by the various methods that are invoked.

As can be seen, the syntax of this example is simpler than the Java version of the class, written using the same algorithm and names:

  /* Rainbow.java -- a simple graphics Applet */
  import java.awt.*;
  import java.applet.*;
  public class Rainbow extends Applet {
    public void paint(Graphics g){
      int maxx=size().width-1;
      int maxy=size().height-1;
      for(int y=0; y<=maxy; y++){
        Color col=Color.getHSBColor((float)y/(float)maxy, 1, 1);
        g.setColor(col);
        g.drawRect(0,y,maxx,y);
      }
    }
  }

In this particular example, there are 74% more lexical tokens and 55% more characters in the Java version (after insignificant blanks and comments have been removed from both versions).  In larger classes, excesses of around 30-40% are more typical.

Performance and binary classes

Some of the the simplifications shown in the example are the result of using a single number model, based on decimal arithmetic.  Decimal arithmetic, however, is rarely available in hardware, and hence is inherently slower than binary arithmetic.  One must therefore consider the effect that this has on performance.

In most cases this need not be a problem; measurements of Rexx programs over the years suggest that the majority of applications spend 8% or less of their time in decimal arithmetic routines.  However, there are applications that use arithmetic heavily (for example: image processing, compression and decompression, or scientific calculations), and for these the cost of software arithmetic may be unacceptable.

It turns out that a solution for these problem cases can be made to be very simple.  If you add the keyword 'binary' to the class instruction, it tells NetRexx to use the primitive binary types for variables and operations wherever possible.  In the 'Rainbow' example -- with no other changes to the code -- the types and casts used in the generated code will be exactly the same as in the hand-crafted Java code, and the applet runs with no performance penalty compared to the Java version.  In fact, in this case, the Rexx string class and decimal arithmetic are not used at all.

Using the binary option exposes the programmer to overflows in integers, of course, just as in the Java version, so it's best reserved for use when performance is critical for a specific class.

Mike Cowlishaw
IBM Fellow
mfc@uk.ibm.com


See the Nov '98 issue of the RexxLA Newsletter for the conclusion.