The NetRexx Tutorial
- NetRexx for REXXers
NetRexx Tutorial - NetRexx for REXXers


NetRexx for REXXers

Introduction

In this chapter we analyse the main differences between the Classical REXX and the NetRexx languages.

NetRexx is NOT REXX, and this you will see from all the following sections.

 
 *** This section is: 
  
 *** and will be available in next releases

NetRexx is compiled, and not interpreted.

One of the biggest differences that REXX (or ooREXX) users will find in NetRexx is the fact that now you need to compile your program.

The usual approach:

 
LOOP till it works
  edit program
  run program
END
 

has now an extra step:

 
LOOP till it works
  edit program
  compile program
  run program
END
 

Not only, but since the object is a Java class, you also must call the program using java.

Differences.

This sections covers all the instructions that are changed, between REXX and NetRexx.

Continuation Character.

The continuation character is different in NetRexx. The reason is that the "old" REXX one ( the ",") could be difficult to read if (as usually happens) you where calling a function or a procedure.

 
REXX      result = myfunction( arg1 , ,
                                arg2 )

NetRexx   result = myfunction( arg1 , -
                                arg2 )
 

Entering Arguments.

In REXX we use the instruction parse pull, or the simple pull to get arguments from the keyboard.

 
REXX      say 'Enter Name'
           parse pull upper name .

NetRexx   say 'Enter Name'
           parse ask.upper() name .
 

STEMs and ARRAYS.

The STEMs are present in NetRexx, but they're called with a different name. They're are called ARRAYs and the compound variable separator is not the "." but the "[ ]" characters. Like STEMS, ARRAY should be initialised to a value.

 
REXX      list. = "
           list.0 = 2
           list.1 = 'Test'
           list.2 = 'Toast'

NetRexx   list  = "
           list[0] = 2
           list[1] = 'Test'
           list[2] = 'Toast'
 

Dealing with multidimensional arrays use the "," character to separate the dimensions; in REXX you still were using the "." .

 
REXX      list.1.2 = 4
           list.i.j = 6

NetRexx   list[1,2] = 4
           list[i,j] = 2
 

function calls

Any internal NetRexx function is called in an Object Oriented fashion.

 
REXX      n = abs(n)

NetRexx   n = n.abs()

REXX      sn = right(s,2,'0')

NetRexx   sn = s.right(2,'0')
 

ALL the functions are effected. NOTE: This is clearly a major change. I had a bit of hard time to get used to it, but after an initial rejection, I find it more "natural".

Look at this example:

 
REXX      bin = x2b(c2x(s))

NetRexx   bin = s.c2x.x2b()
 

From the second writing it comes very much more evident that what I'm trying to do is a:

 
    c2x.x2b
     =====
      c2b
 

conversion.

xrange()

There is NO xrange instruction in NetRexx.

 
REXX      str = xrange('00'X,'1F'X)

NetRexx   str = '\x00'.sequence('\x1F')
 

xrange() is implemented in xstring.

HEX characters.

You use a different method to enter HEX quantities in NetRexx.

 
REXX      crlf = '0D0A'X

NetRexx   crlf = '\x0D\x0A'
 

Missing instructions.

find() and index()

The find() and index() functions have always been available in the VM/CMS implementation of REXX. Indeed, they've never been in the "official" REXX.

 
REXX:     find(list,item)
              |
              V
NetRexx:  list.wordpos(item)
 
 
REXX:     index(string,item)
              |
              V
NetRexx:  list.pos(item)
 

Of course you can write your own find() and index() that just do pos() and wordpos().

Additions

upper() and lower()

The upper() and lower() functions are native in NetRexx. They were not available in native REXX.

 

/* */                REXX

str = str.lower()    NetRexx
str = str.upper()
 

Associative Arrays

Indexed Strings are used to set up "Associative Arrays" in which the sunscript is not necessarily numeric.

In "classic" REXX you would code:

 
+----------------------------------------------------------------------+
| authorizelist = 'BOB JENNY PENNY'                                    |01
| authorize.jenny = 'list cat'                                         |02
| authorize.bob  = 'list cat write'                                    |03
| authorize.penny = 'list'                                             |04
| list = authorizelist                                                 |05
| do while list <> ''                                                  |06
|   parse var list id list                                             |07
|   say id 'can do "'authorize.id'".'                                  |08
| end                                                                  |09
| exit                                                                 |10
+----------------------------------------------------------------------+
                                                                asar.rex

 
+----------------------------------------------------------------------+
| authorize = ''                                                       |01
| authorize['jenny'] = 'list cat'                                      |02
| authorize['bob'] = 'list cat write'                                  |03
| authorize['penny'] = 'list'                                          |04
| loop id over authorize                                               |05
|   say id 'can do "'authorize[id]'".'                                 |06
| end                                                                  |07
| exit                                                                 |08
+----------------------------------------------------------------------+
                                                                asar.nrx
Download the source for the asar.nrx example

Program structure

This is probably the biggest difference between REXX and NetRexx. Subroutines and procedures like you knew them in REXX disappear, and the concept of method replaces them.

The following are some small examples.

Argument passing

 
+----------------------------------------------------------------------+
| /* compute the mean value of two numbers                             |01
|  */                                                                  |02
| parse arg n1 n2 .                                                    |03
| say 'The mean value of' n1 'and' n2 'is:' mean(n1,n2)'.'             |04
| exit                                                                 |05
|                                                                      |06
| mean: procedure;                                                     |07
|   parse arg i1 , i2                                                  |08
|   m = (i1+i2)/2                                                      |09
|   return m                                                           |10
+----------------------------------------------------------------------+
                                                                tnr1.rex

 
+----------------------------------------------------------------------+
| -- tnr1.nrx                                                          |01
| --   Show the usage of a function                                    |02
| class tnr1                                                           |03
|                                                                      |04
|   method mean(i1=Rexx,i2=Rexx) public static                         |05
|     out = (i1+i2)/2                                                  |06
|     return out                                                       |07
|                                                                      |08
|   method main(args=String[]) public static                           |09
|     arg = Rexx(args)                                                 |10
|     parse arg n1 n2 .                                                |11
|     say 'mean of' n1 'and' n2 'is:' mean(n1,n2)'.'                   |12
|     exit 0                                                           |13
+----------------------------------------------------------------------+
                                                                tnr1.nrx
Download the source for the tnr1.nrx example

Exposing variables

 
+----------------------------------------------------------------------+
| /* tnr2.rex                                                          |01
|  */                                                                  |02
| avar1 = 'MAIN'                                                       |03
| avar2 = 'MAIN'                                                       |04
| call sub1                                                            |05
| say avar1                                                            |06
| say avar2                                                            |07
| exit                                                                 |08
|                                                                      |09
| sub1: procedure expose avar1                                         |10
|   avar1 = 'SUB1'                                                     |11
|   avar2 = 'SUB1'                                                     |12
|   say avar1                                                          |13
|   say avar2                                                          |14
|   return                                                             |15
+----------------------------------------------------------------------+
                                                                tnr2.rex

 
+----------------------------------------------------------------------+
| class tnr2                                                           |01
|   properties public static                                           |02
|     avar1                                                            |03
|                                                                      |04
|   method sub1() public static                                        |05
|     avar1 = 'SUB1'     -- will be changed                            |06
|     avar2 = 'SUB1'     -- will NOT be changed                        |07
|     say avar1                                                        |08
|     say avar2                                                        |09
|                                                                      |10
|   method main(args=String[]) public static                           |11
|     args = args                                                      |12
|     avar1 = 'MAIN'                                                   |13
|     avar2 = 'MAIN'                                                   |14
|     sub1()                                                           |15
|     say avar1                                                        |16
|     say avar2                                                        |17
|     exit 0                                                           |18
+----------------------------------------------------------------------+
                                                                tnr2.nrx
Download the source for the tnr2.nrx example
 
 *** This section is: 
  
 *** and will be available in next releases

This really got me!

In this section I collect all "nasty" problems that I found in NetRexx, and which probably were due to my REXX background. I hope that this collection will avoid you loosing the time I did lost to find out why a particular algorithm was not working.

Variable and array/stem with the same name.

In REXX you can have variables that share the same name of a STEM. You can happily write:

 
   line = line.i
 

and line (a variable), will get the value of the stem variable line.i.

 
+----------------------------------------------------------------------+
| line.1 = 'Test line'                                                 |01
| line.2 = 'another one'                                               |02
| line.3 = 'last one'                                                  |03
| do i = 1 to 3                                                        |04
|   line = line.i                                                      |05
|   say line                                                           |06
| end                                                                  |07
| exit                                                                 |08
+----------------------------------------------------------------------+
                                                                tgm1.rex

In NetRexx such approach will not work. In the following program, infact, the statement:

 
   line = line[i]
 

will just initialise the whole array line[] to line[1]. SO ALL THE ARRAY INFORMATION WILL BE OVERWRITTEN.

 
+----------------------------------------------------------------------+
| line = Rexx(")                                                      |01
| line[1] = 'test line'                                                |02
| line[2] = 'another one'                                              |03
| line[3] = 'last one'                                                 |04
| loop i = 1 to 3                                                      |05
|   line = line[i]                                                     |06
|   say line                                                           |07
| end                                                                  |08
+----------------------------------------------------------------------+
                                                                tgm1.nrx
Download the source for the tgm1.nrx example

In REXX, you would have achieved the same result writing:

 
   line. = line.1
 

Chapter FAQ.

Would it be possible to make a REXX to NetRexx translator?

Yes, as you could see a lot of the differences in the syntax could be made in an automatic way. It is simple to translate an instruction like:

 
   s1 = left(s,3)
 

to:

 
   s1 = s.left(3)
 

I plan to write some code that will do a 'first step' translation. So far I know nobody who did it.

Summary

 
 *** This section is: 
  
 *** and will be available in next releases


File: nr_28.html.

The contents of this WEB page are Copyright © 1997 by Pierantonio Marchesini / ETH Zurich.

Last update was done on 18 May 1998 21:48:03(GMT +2).