home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / netrexx.zip / NetRexx / nrover.doc < prev    next >
Text File  |  1998-12-22  |  34KB  |  805 lines

  1.                                                            NetRexx 1.148
  2. NetRexx language quick start
  3. ============================
  4.  
  5. Copyright(c) IBM Corporation, 1996, 1997.  All rights reserved.
  6.  
  7. Introduction
  8. """"""""""""
  9. NetRexx is a new programming language derived from both Rexx and
  10. Java(tm); it is a dialect of Rexx that retains the portability and
  11. efficiency of Java, while being as easy to learn and to use as Rexx.
  12.  
  13. NetRexx is an effective alternative to the Java language.  With NetRexx,
  14. you can create programs and applets for the Java environment more easily
  15. than by programming in Java.  Using Java classes is especially easy in
  16. NetRexx as you rarely have to worry about all the different types of
  17. numbers and strings that Java requires.
  18.  
  19. This document summarises the main features of NetRexx, and is intended
  20. to help you start using it quickly.  It's assumed that you have some
  21. knowledge of programming in a language such as Rexx, C, BASIC, or Java,
  22. but a knowledge of 'object-oriented' programming isn't needed.
  23.  
  24. This is not a complete tutorial, though -- think of it more as a
  25. 'taster'; it covers the main points of the language and shows some
  26. examples you can try or modify.
  27.  
  28. For more samples (and examples of using Java classes from NetRexx), and
  29. for more formal details of the language, please see the other NetRexx
  30. documents at http://www2.hursley.ibm.com/netrexx/ -- you'll find the
  31. NetRexx software to download there, too.
  32.  
  33. NetRexx programs
  34. """"""""""""""""
  35. The structure of a NetRexx program is extremely simple.  This sample
  36. program, 'toast', is complete, documented, and executable as it stands:
  37.  
  38.   /* This wishes you the best of health. */
  39.   say 'Cheers!'
  40.  
  41. This program consists of two lines: the first is an optional comment
  42. that describes the purpose of the program, and the second is a SAY
  43. statement.  SAY simply displays the result of the expression following
  44. it -- in this case just a literal string (you can use either single or
  45. double quotes around strings, as you prefer).
  46.  
  47. To run this program, edit a file called toast.nrx and copy or paste the
  48. two lines above into it.  You can then use the NetRexxC Java program to
  49. compile it, and the java command to run it:
  50.  
  51.   java COM.ibm.netrexx.process.NetRexxC toast
  52.   java toast
  53.  
  54. You may also be able to use the NETREXXC command to compile and run the
  55. program with a single command (details may vary -- see the installation
  56. and user's guide document):
  57.  
  58.  netrexxc toast -run
  59.  
  60. Of course, NetRexx can do more than just display a character string.
  61. Although the language has a simple syntax, and has a small number of
  62. statement types, it is powerful; the language allows full access to the
  63. rapidly growing collection of Java programs known as 'class libraries',
  64. and allows new class libraries to be written in NetRexx.
  65.  
  66. The rest of this document introduces most of the features of NetRexx.
  67. Since the economy, power, and clarity of expression in NetRexx is best
  68. appreciated with use, you are urged to try using the language yourself.
  69.  
  70. Expressions and variables
  71. """""""""""""""""""""""""
  72. Like SAY in the 'toast' example, many statements in NetRexx include
  73. _expressions_ that will be evaluated.  NetRexx provides arithmetic
  74. operators (including integer division, remainder, and power operators),
  75. several concatenation operators, comparison operators, and logical
  76. operators.  These can be used in any combination within a NetRexx
  77. expression (provided, of course, that the data values are valid for
  78. those operations).
  79.  
  80. All the operators act upon strings of characters (known as _Rexx
  81. strings_), which may be of any length (typically limited only by the
  82. amount of storage available).  Quotes (either single or double) are used
  83. to indicate literal strings, and are optional if the literal string is
  84. just a number.  For example, the expressions:
  85.  
  86.   '2' + '3'
  87.   '2' + 3
  88.     2 + 3
  89.  
  90. would all result in '5'.
  91.  
  92. The results of expressions are often assigned to _variables_, using a
  93. conventional assignment syntax:
  94.  
  95.   var1=5            /* sets var1 to '5'    */
  96.   var2=(var1+2)*10  /* sets var2 to '70' */
  97.  
  98. You can write the names of variables (and keywords) in whatever mixture
  99. of uppercase and lowercase that you prefer; the language is not
  100. case-sensitive.
  101.  
  102. This next sample program, 'greet', shows expressions used in various
  103. ways:
  104.  
  105.   /* A short program to greet you.                      */
  106.   /* First display a prompt:                            */
  107.   say 'Please type your name and then press ENTER:'
  108.   answer=ask               /* Get the reply into ANSWER */
  109.  
  110.   /* If no name was entered, then use a fixed greeting, */
  111.   /* otherwise echo the name politely.                  */
  112.   if answer='' then say 'Hello Stranger!'
  113.                else say 'Hello' answer'!'
  114.  
  115. After displaying a prompt, the program reads a line of text from the
  116. user ('ask' is a keyword provided by NetRexx) and assigns it to the
  117. variable ANSWER.  This is then tested to see if any characters were
  118. entered, and different actions are taken accordingly; if the user typed
  119. 'Fred' in response to the prompt, then the program would display:
  120.  
  121.   Hello Fred!
  122.  
  123. As you see, the expression on the last SAY (display) statement
  124. concatenated the string 'Hello' to the value of variable ANSWER with a
  125. blank in between them (the blank is here a valid operator, meaning
  126. 'concatenate with blank').  The string '!' is then directly concatenated
  127. to the result built up so far.  These unobtrusive operators (the _blank
  128. operator_ and abuttal) for concatenation are very natural and easy to
  129. use, and make building text strings simple and clear.
  130.  
  131. The layout of statements is very flexible.  In the 'greet' example, for
  132. instance, the IF statement could be laid out in a number of ways,
  133. according to personal preference.  Line breaks can be added at either
  134. side of the THEN (or following the ELSE).
  135.  
  136. In general, statements are ended by the end of a line.  To continue a
  137. statement to a following line, you can use a hyphen (minus sign) just as
  138. in English:
  139.  
  140.   say 'Here we have an expression that is quite long, so' -
  141.       'it is split over two lines'
  142.  
  143. This acts as though the two lines were all on one line, with the hyphen
  144. and any blanks around it being replaced by a single blank.  The net
  145. result is two strings concatenated together (with a blank in between)
  146. and then displayed.
  147.  
  148. When desired, multiple statements can be placed on one line with the
  149. aid of the semicolon separator:
  150.  
  151.   if answer='Yes' then do; say 'OK!'; exit; end
  152.  
  153. (many people find multiple statements on one line hard to read, but
  154. sometimes it is convenient).
  155.  
  156. Control statements
  157. """"""""""""""""""
  158. NetRexx provides a selection of _control_ statements, whose form was
  159. chosen for readability and similarity to natural languages.  The control
  160. statements include IF... THEN... ELSE (as in the 'greet' example) for
  161. simple conditional processing:
  162.  
  163.   if ask='Yes' then say "You answered Yes"
  164.                else say "You didn't answer Yes"
  165.  
  166. SELECT... WHEN... OTHERWISE... END for selecting from a number of
  167. alternatives:
  168.  
  169.   select
  170.     when a>0 then say 'greater than zero'
  171.     when a<0 then say 'less than zero'
  172.     otherwise say 'zero'
  173.     end
  174.  
  175. DO... END for grouping:
  176.  
  177.   if a>3 then do
  178.     say 'A is greater than 3; it will be set to zero'
  179.     a=0
  180.     end
  181.  
  182. and LOOP... END for repetition:
  183.  
  184.   loop i=1 to 10    /* repeat 10 times; I changes from 1 to 10 */
  185.     say i
  186.     end
  187.  
  188. The LOOP statement can be used to step a variable TO some limit, BY some
  189. increment, FOR a specified number of iterations, and WHILE or UNTIL some
  190. condition is satisfied.  LOOP FOREVER is also provided.  Loop execution
  191. may be modified by LEAVE and ITERATE statements that significantly
  192. reduce the complexity of many programs.
  193.  
  194. NetRexx arithmetic
  195. """"""""""""""""""
  196. Character strings in NetRexx are commonly used for arithmetic (assuming,
  197. of course, that they represent numbers).  The string representation of
  198. numbers can include integers, decimal notation, and exponential
  199. notation; they are all treated the same way.  Here are a few:
  200.  
  201.   '1234'
  202.   '12.03'
  203.   '-12'
  204.   '120e+7'
  205.  
  206. The arithmetic operations in NetRexx are designed for people rather than
  207. machines, so are decimal rather than binary, do not overflow at certain
  208. values, and follow the rules that people use for arithmetic. The
  209. operations are completely defined by the ANSI standard for Rexx, so
  210. correct implementations will always give the same results.
  211.  
  212. An unusual feature of NetRexx arithmetic is the NUMERIC statement: this
  213. may be used to select the _arbitrary precision_ of calculations.  You
  214. may calculate to whatever precision that you wish, for financial
  215. calculations, perhaps, limited only by available memory.  For example:
  216.  
  217.   numeric digits 50
  218.   say 1/7
  219.  
  220. which would display
  221.  
  222.   0.14285714285714285714285714285714285714285714285714
  223.  
  224. The numeric precision can be set for an entire program, or be adjusted
  225. at will within the program.  The NUMERIC statement can also be used to
  226. select the notation (_scientific_ or _engineering_) used for numbers in
  227. exponential format.
  228.  
  229. NetRexx also provides simple access to the native binary arithmetic of
  230. computers.  Using binary arithmetic offers many opportunities for
  231. errors, but is useful when performance is paramount.  You select binary
  232. arithmetic by adding the statement:
  233.  
  234.   options binary
  235.  
  236. at the top of a NetRexx program.  The language processor will then use
  237. binary arithmetic instead of Rexx decimal arithmetic for calculations,
  238. throughout the program.
  239.  
  240. Doing things with strings
  241. """""""""""""""""""""""""
  242. Another thing Rexx is good for is manipulating strings in various ways.
  243. NetRexx provides the same facilities as Rexx, but with a syntax that is
  244. more like Java or other similar languages:
  245.  
  246.   phrase='Now is the time for a party'
  247.   say phrase.word(7).pos('r')
  248.  
  249. The second line here can be read from left to right as "take the
  250. variable 'phrase', find the seventh word, and then find the position
  251. of the first 'r' in that word".  This would display '3' in this case,
  252. because 'r' is the third character in 'party'.
  253.  
  254. (In Rexx, the second line above would have been written using nested
  255. function calls:
  256.  
  257.   say pos('r', word(phrase, 7))
  258.  
  259. which is not as easy to read; you have to follow the nesting and then
  260. backtrack from right to left to work out exactly what's going on.)
  261.  
  262. In the NetRexx syntax, at each point in the sequence of operations some
  263. routine is acting on the result of what has gone before.  These routines
  264. are called _methods_, to make the distinction from functions (which act
  265. in isolation).  NetRexx provides (as methods) most of the functions that
  266. were evolved for Rexx, for example:
  267.  
  268.   o changestr (change all occurrences of a substring to another)
  269.   o copies (make multiple copies of a string)
  270.   o lastpos (find rightmost occurrence)
  271.   o left and right (return leftmost/rightmost character(s))
  272.   o reverse (swap end-to-end)
  273.   o space (pad between words with fixed spacing)
  274.   o strip (remove leading and/or trailing white space)
  275.   o pos and wordpos (find the position of string or a word in a string)
  276.   o verify (check the contents of a string for selected characters)
  277.   o word, wordindex, wordlength, and words (work with words)
  278.  
  279. These and the others like them, and the parsing described in the next
  280. section, make it especially easy to process text with NetRexx.
  281.  
  282. Parsing strings
  283. """""""""""""""
  284. The previous section described some of the string-handling facilities
  285. available; NetRexx also provides Rexx string parsing, which is a fast
  286. and simple way of breaking up strings of characters using simple pattern
  287. matching.
  288.  
  289. A PARSE statement first specifies the string to be parsed, often taken
  290. simply from a variable.  This is followed by a _template_ which
  291. describes how the string is to be split up, and where the pieces are to
  292. be put.
  293.  
  294. --- Parsing into words ---
  295.  
  296. The simplest form of parsing template consists of a list of variable
  297. names.  The string being parsed is split up into words (sequences of
  298. characters separated by blanks), and each word from the string is
  299. assigned (copied) to the next variable in turn, from left to right.  The
  300. final variable is treated specially in that it will be assigned a copy
  301. of whatever is left of the original string and may therefore contain
  302. several words. For example, in:
  303.  
  304.   parse 'This is a sentence.'   v1 v2 v3
  305.  
  306. the variable v1 would be assigned the value 'This', v2 would be assigned
  307. the value 'is', and v3 would be assigned the value 'a sentence.'.
  308.  
  309. --- Literal patterns ---
  310.  
  311. A literal string may be used in a template as a pattern to split up the
  312. string.  For example
  313.  
  314.   parse 'To be, or not to be?'   w1 ',' w2 w3 w4
  315.  
  316. would cause the string to be scanned for the comma, and then split at
  317. that point; each section is then treated in just the same way as the
  318. whole string was in the previous example.
  319.  
  320. Thus, w1 would be set to 'To be', w2 and w3 would be assigned the values
  321. 'or' and 'not', and w4 would be assigned the remainder: 'to be?'.  Note
  322. that the pattern itself is not assigned to any variable.
  323.  
  324. The pattern may be specified as a variable, by putting the variable name
  325. in parentheses.  The following statements:
  326.  
  327.   comma=','
  328.   parse 'To be, or not to be?'   w1 (comma) w2 w3 w4
  329.  
  330. therefore have the same effect as the previous example.
  331.  
  332. --- Positional patterns ---
  333.  
  334. The third kind of parsing mechanism is the numeric positional pattern.
  335. This works just like the string pattern except in syntax; it specifies a
  336. column number (which may be absolute or relative, and derived from a
  337. variable if necessary).
  338.  
  339. String patterns and positional patterns can be mixed.
  340.  
  341. Indexed variables
  342. """""""""""""""""
  343. NetRexx provides an indexed variable mechanism, adapted from the
  344. compound variables of Rexx.
  345.  
  346. NetRexx string variables can be referred to simply by name, or also by
  347. their name qualified by another string (the _index_).  When an index is
  348. used, a value associated with that index is either set or extracted; in
  349. the latter case, the initial value of the variable is returned if the
  350. index has not been used to set a value.  For example, the program:
  351.  
  352.   dognoise='bark'
  353.   dognoise['pup']='yap'
  354.   dognoise['bulldog']='grrrrr'
  355.   say dognoise['pup'] dognoise['terrier'] dognoise['bulldog']
  356.  
  357. would display
  358.  
  359.   yap bark grrrrr
  360.  
  361. Any expression may be used inside the brackets; the resulting string is
  362. used as the index.  Multiple dimensions may be used, if required:
  363.  
  364.   dognoise='bark'
  365.   dognoise['spaniel', 'brown']='ruff'
  366.   say dognoise['spaniel', 'brown'] dognoise['terrier']
  367.  
  368. which would display
  369.  
  370.   ruff bark
  371.  
  372. Here's a more complex example, a test program with a function (called
  373. a _constant method_ in NetRexx) that removes all duplicate words from a
  374. string of words:
  375.  
  376.   /* justonetest.nrx -- test the justone function.        */
  377.   say justone('to be or not to be')    /* simple testcase */
  378.   exit
  379.  
  380.   /* This removes duplicate words from a string, and      */
  381.   /* shows the use of a variable (HADWORD) which is       */
  382.   /* indexed by arbitrary data (words).                   */
  383.   method justone(wordlist) constant
  384.     hadword=0           /* show all possible words as new */
  385.     outlist=''              /* initialize the output list */
  386.     loop while wordlist\=''    /* loop while we have data */
  387.       /* next, split WORDLIST into first word and residue */
  388.       parse wordlist word wordlist
  389.       if hadword[word] then iterate   /* loop if had word */
  390.       hadword[word]=1   /* remember we have had this word */
  391.       outlist=outlist word     /* add word to output list */
  392.       end
  393.     return outlist           /* finally return the result */
  394.  
  395. Running this program would display just the four words 'to', 'be', 'or',
  396. and 'not'.
  397.  
  398. This example also uses the built-in _string parsing_ provided by the
  399. PARSE statement.  In this instance, the value of WORDLIST is parsed,
  400. with the first word of the value being assigned to the variable WORD and
  401. the remainder being assigned back to WORDLIST (replacing the original
  402. value).
  403.  
  404. [Author's note: since the notation for indexed variables looks just like
  405. arrays (see the next section), but does not not suffer the restrictions
  406. of arrays, I like to call them _disarrays_.]
  407.  
  408. Arrays
  409. """"""
  410. NetRexx also supports Java's fixed-size _arrays_.  These are an ordered
  411. set of items, indexed by integers.  To use an array, you first have to
  412. construct it; an individual item may then be selected by an index whose
  413. value must be in the range 0 through N-1, where N is the number of items
  414. in the array:
  415.  
  416.   array=String[3]            -- make an array of three Java Strings
  417.   array[0]='String one'      -- set each array item
  418.   array[1]='Another string'
  419.   array[2]='foobar'
  420.   loop i=0 to 2              -- display them
  421.     say array[i]
  422.     end
  423.  
  424. This example also shows NetRexx _line comments_; the sequence '--'
  425. (outside of literal strings or '/*' comments) indicates that the
  426. remainder of the line is not part of the program and is commentary.
  427.  
  428. Tracing
  429. """""""
  430. Defined as part of the language, NetRexx tracing often provides useful
  431. debugging information.  The flow of execution of programs may be traced,
  432. and the execution trace can be viewed as it occurs or captured in a
  433. file.  The trace can show each clause as it is executed, and optionally
  434. show the results of expressions, _etc._  For example, the program:
  435.  
  436.   trace results
  437.   number=1/7
  438.   parse number before '.' after
  439.   say after'.'before
  440.  
  441. would result in the trace:
  442.  
  443.   2 *=*   number=1/7
  444.     >v> number "0.142857143"
  445.   3 *=*   parse number before '.' after
  446.     >v> before "0"
  447.     >v> after "142857143"
  448.   4 *=*   say after'.'before
  449.     >>> "142857143.0"
  450.  
  451. where the lines marked with '*=*' are the statements in the program,
  452. lines with '>v>' show results assigned to local variables, and
  453. lines with '>>>' show results of un-named expressions.
  454.  
  455. Exception and error handling
  456. """"""""""""""""""""""""""""
  457. NetRexx doesn't have a GOTO statement, but a SIGNAL statement is
  458. provided for abnormal transfer of control, such as when something
  459. unusual occurs.  Using SIGNAL raises an _exception_; all control
  460. statements are then 'unwound' until the exception is caught by a control
  461. statement that specifies a suitable CATCH statement for handling the
  462. exception.
  463.  
  464. Exceptions are also raised when various errors occur, such as attempting
  465. to divide a number by zero.  For example:
  466.  
  467.   say 'Please enter a number:'
  468.   number=ask
  469.   do
  470.     say 'The reciprocal of' number 'is:' 1/number
  471.   catch Exception
  472.     say 'Sorry, could not divide "'number'" into 1'
  473.   end
  474.  
  475. Here, the CATCH statement will catch any exception that is raised when
  476. the division is attempted (conversion error, divide by zero, etc.).
  477.  
  478. Any control statement that ends with END (DO, LOOP, or SELECT) may be
  479. modified with one or more CATCH statements to handle exceptions.
  480.  
  481. Things that aren't strings
  482. """"""""""""""""""""""""""
  483. In all the examples so far, the data being manipulated (numbers, words,
  484. and so on) are expressed as a string of characters.  Many things,
  485. however, can be expressed more easily in some other way, so NetRexx
  486. allows variables to refer to other collections of data, which are known
  487. as _objects_.
  488.  
  489. Objects are defined by a name that lets NetRexx determine the data
  490. and methods that are associated with the object.  This name identifies
  491. the type of the object, and is usually called the _class_ of the object.
  492.  
  493. For example, an object of class Oblong might represent an oblong to be
  494. manipulated and displayed.  The oblong could be defined by two values:
  495. its width and its height.  These values are called the _properties_ of
  496. the Oblong class.
  497.  
  498. Most methods associated with an object perform operations on the object;
  499. for example a 'size' method might be provided to change the size of an
  500. Oblong object.  Other methods are used to construct objects (just as
  501. for NetRexx arrays, an object must be constructed before it can be
  502. used).  In NetRexx and Java, these _constructor_ methods always have the
  503. same name as the class of object that they build (Oblong, in this case).
  504.  
  505. Here's how an Oblong class might be written in NetRexx (by convention,
  506. this would be written in a file called Oblong.nrx; Java expects the name
  507. of the file to match the name of the class inside it):
  508.  
  509.   /* Oblong.nrx -- simple oblong class */
  510.   class Oblong
  511.     width       -- size (X dimension)
  512.     height      -- size (Y dimension)
  513.  
  514.     /* Constructor method to make a new oblong */
  515.     method Oblong(new_width, new_height)
  516.       -- when we get here, a new (uninitialized) object has been
  517.       -- created.  Copy the parameters we have been given to the
  518.       -- properties of the object:
  519.       width=new_width; height=new_height
  520.  
  521.     /* Change the size of an Oblong */
  522.     method size(new_width, new_height) returns Oblong
  523.       width=new_width; height=new_height
  524.       return this   -- return the resized object
  525.  
  526.     /* Change the size of an Oblong, relative to its current size */
  527.     method sizerelative(rel_width, rel_height) returns Oblong
  528.       width=width+rel_width; height=height+rel_height
  529.       return this
  530.  
  531.     /* 'Print' what we know about the oblong */
  532.     method print
  533.       say 'Oblong' width 'x' height
  534.  
  535. To summarize:
  536.  
  537.   1. A class is started by the 'class' statement, which names the
  538.      class.
  539.  
  540.   2. The class statement is followed by a list of the properties of the
  541.      object.  These can be assigned initial values, if required.
  542.  
  543.   3. The properties are followed by the methods of the object.  Each
  544.      method is introduced by a method statement which names the method
  545.      and describes the arguments that must be supplied to the method.
  546.      The body of the method is ended by the next method statement (or
  547.      by the end of the file).
  548.  
  549. The Oblong.nrx file is compiled just like any other NetRexx program, and
  550. should create a _class file_ called Oblong.class.  Here's a program to
  551. try out the Oblong class:
  552.  
  553.   /* tryOblong.nrx -- try the Oblong class */
  554.  
  555.   first=Oblong(5,3)              -- make an oblong
  556.   first.print                    -- show it
  557.   first.sizerelative(1,1).print  -- enlarge it and print it again
  558.  
  559.   second=Oblong(1,2)             -- make another oblong
  560.   second.print                   -- and print it
  561.  
  562. when 'tryOblong.nrx' is compiled, you'll notice that the cross-reference
  563. listing of variables shows that the variables 'first' and 'second' have
  564. type 'Oblong'.  These variables refer to Oblongs, just as the variables
  565. in earlier examples referred to Rexx strings.
  566.  
  567. Once a variable has been assigned a type, it can only refer to objects
  568. of that type.  This helps avoid errors where a variable refers to an
  569. object that it wasn't meant to.
  570.  
  571. --- Programs are classes, too ---
  572.  
  573. It's worth pointing out, here, that all the example programs in this
  574. document are in fact classes (you may have noticed that compiling them
  575. creates xxx.class files, where xxx is the name of the source file).  The
  576. Java environment will allow a class to run as a stand-alone
  577. _application_ if it has a constant method called 'main' which takes an
  578. array of Java Strings as its argument.
  579.  
  580. If necessary (that is, if there is no class statement) NetRexx
  581. automatically adds the necessary class and method statement, and also
  582. a statement to convert the array of strings (each of which holds one
  583. word from the command string) to a single Rexx string.  The 'toast'
  584. example could therefore have been written:
  585.  
  586.   /* This wishes you the best of health. */
  587.   class toast
  588.     method main(argwords=String[]) constant; arg=Rexx(argwords)
  589.       say 'Cheers!'
  590.  
  591.  
  592. Extending classes
  593. """""""""""""""""
  594. It's common, when dealing with objects, to take an existing class and
  595. extend it.  One way to do this is to modify the source code of the
  596. original class -- but this isn't always available, and with many
  597. different people modifying a class, classes could rapidly get
  598. over-complicated.
  599.  
  600. Languages that deal with objects, like NetRexx, therefore allow new
  601. classes of objects to be set up which are derived from existing classes.
  602. For example, if you wanted a different kind of Oblong in which the
  603. Oblong had a new property that would be used when printing the Oblong as
  604. a rectangle, you might define it thus:
  605.  
  606.   /* charOblong.nrx -- an oblong class with character */
  607.   class charOblong extends Oblong
  608.     printchar       -- the character for display
  609.  
  610.     /* Constructor method to make a new oblong with character */
  611.     method charOblong(new_width, new_height, new_printchar)
  612.       super(new_width, new_height)      -- make an oblong
  613.       printchar=new_printchar           -- and set the print character
  614.  
  615.     /* 'Print' the oblong */
  616.     method print
  617.       loop for super.height
  618.         say printchar.copies(super.width)
  619.         end
  620.  
  621. There are several things worth noting about this example:
  622.  
  623.   1. The 'extends Oblong' on the class statement means that this class
  624.      is an extension of the Oblong class.  The properties and methods of
  625.      the Oblong class are _inherited_ by this class (that is, appear as
  626.      though they were part of this class).
  627.  
  628.      Another common way of saying this is that 'charOblong' is a
  629.      _subclass_ of 'Oblong' (and 'Oblong' is the _superclass_ of
  630.      'charOblong').
  631.  
  632.   2. This class adds the 'printchar' property to the properties already
  633.      defined for Oblong.
  634.  
  635.   3. The constructor for this class takes a width and height (just like
  636.      Oblong) and adds a third argument to specify a print character.  It
  637.      first invokes the constructor of its superclass (Oblong) to build
  638.      an Oblong, and finally sets the printchar for the new object.
  639.  
  640.   4. The new charOblong object also prints differently, as a rectangle
  641.      of characters, according to its dimension.  The 'print' method (as
  642.      it has the same name and arguments -- none -- as that of the
  643.      superclass) replaces (overrides) the 'print' method of Oblong.
  644.  
  645.   5. The other methods of Oblong are not overridden, and therefore can
  646.      be used on charOblong objects.
  647.  
  648. The charOblong.nrx file is compiled just like Oblong.nrx was, and
  649. should create a file called charOblong.class.  Here's a program to
  650. try it out:
  651.  
  652.   /* trycharOblong.nrx -- try the charOblong class */
  653.  
  654.   first=charOblong(5,3,'#')      -- make an oblong
  655.   first.print                    -- show it
  656.   first.sizerelative(1,1).print  -- enlarge it and print it again
  657.  
  658.   second=charOblong(1,2,'*')     -- make another oblong
  659.   second.print                   -- and print it
  660.  
  661. This should create the two charOblong objects, and print them out in a
  662. simple 'character graphics' form.  Note the use of the method
  663. 'sizerelative' from Oblong to resize the charOblong object.
  664.  
  665. --- Optional arguments ---
  666.  
  667. All methods in NetRexx may have optional arguments (omitted from the
  668. right) if desired.  For an argument to be optional, you must supply a
  669. default value.  For example, if the charOblong constructor was to have a
  670. default printchar value, its method statement could have been written:
  671.  
  672.   method charOblong(new_width, new_height, new_printchar='X')
  673.  
  674. which indicates that if no third argument is supplied then 'X' should be
  675. used.  A program creating a charOblong could then simply write:
  676.  
  677.   first=charOblong(5,3)       -- make an oblong
  678.  
  679. which would have the same effect as if 'X' were specified as the third
  680. argument.
  681.  
  682. Binary types and conversions
  683. """"""""""""""""""""""""""""
  684. The Java environment supports, and indeed requires, the notion of
  685. fixed-precision 'primitive' binary types, which correspond closely to
  686. the binary operations usually available at the hardware level in
  687. computers.  In brief, these types are:
  688.  
  689.   o _byte, short, int,_ and _long_ -- signed integers that will fit in
  690.     8, 16, 32, or 64 bits respectively
  691.  
  692.   o _float_ and _double_ -- signed floating point numbers that will fit
  693.     in 32 or or 64 bits respectively.
  694.  
  695.   o _char_ -- an unsigned 16-bit quantity, holding a Unicode character
  696.  
  697.   o _boolean_ -- a 1-bit logical value, representing 'false' or 'true'.
  698.  
  699. Objects of these types are handled specially by the environment 'under
  700. the covers' in order to achieve maximum efficiency; in particular, they
  701. cannot be constructed like other objects -- their value is held
  702. directly.  This distinction rarely matters to the NetRexx programmer: in
  703. the case of string literals an object is constructed automatically; in
  704. the case of an _int_ literal, an object is not constructed.
  705.  
  706. Further, NetRexx automatically allows the conversion between the various
  707. forms of character strings in Java (String, char, char[], and Rexx) and
  708. the primitive types listed above.  The 'golden rule' that is followed by
  709. NetRexx is that any automatic conversion which is applied must not lose
  710. information: either it can be determined at compile time that the
  711. conversion is safe (as in int -> String) or it will be detected at run
  712. time if the conversion fails (as in String -> int).
  713.  
  714. The automatic conversions greatly simplify the writing of programs for
  715. the Java environment: the exact type of numeric and string-like method
  716. arguments rarely needs to be a concern of the programmer.
  717.  
  718. For certain applications where early checking or performance override
  719. other considerations, NetRexx provides options for different treatment
  720. of the primitive types:
  721.  
  722.   1. options strictassign -- ensures exact type matching for all
  723.      assignments.  No conversions (including those from shorter
  724.      integers to longer ones) are applied.  This option provides
  725.      stricter type-checking than Java, and ensures that all types are
  726.      an exact match.
  727.  
  728.   2. options binary -- uses Java fixed precision arithmetic on binary
  729.      types (also, literal numbers, for example, will be treated as
  730.      binary, and local variables will be given 'native' Java types such
  731.      as _int_ or _String_, where possible).
  732.  
  733.      Binary arithmetic currently gives better performance than Rexx
  734.      decimal arithmetic, but places the burden of avoiding overflows and
  735.      loss of information on the programmer.
  736.  
  737. The options statement (which may list more than one option) is placed
  738. before the first class statement in a file.
  739.  
  740. You may also explicitly assign a type to an expression or variable:
  741.  
  742.    i=int 3000000    -- 'i' is an 'int' with initial value 3000000
  743.    j=int 4000000    -- 'j' is an 'int' with initial value 4000000
  744.    k=int            -- 'k' is assigned type 'int', with no initial value
  745.    say i*j          -- carry out multiplication and display the result
  746.    k=i*j            -- carry out multiplication and assign result to 'k'
  747.  
  748. This example also illustrates one difference between 'options nobinary'
  749. and 'options binary'.  With the former (the NetRexx default) the SAY
  750. would display '1.20000000E+13' and a Conversion overflow would be
  751. reported when the same expression is assigned to the variable 'k'.
  752.  
  753. With 'options binary', binary arithmetic would be used for the
  754. multiplications, and so no error would be detected; the SAY would
  755. display '-138625024' and the variable 'k' takes the incorrect result.
  756.  
  757. --- Binary types in practice ---
  758.  
  759. In practice, explicit type assignment is only occasionally needed in
  760. NetRexx.  Those conversions that are necessary for using existing
  761. classes (or those that use 'options binary') are generally automatic.
  762. For example, here is an "Applet" for use by Java-enabled browsers:
  763.  
  764.   /* A simple graphics Applet */
  765.   class Rainbow extends Applet
  766.     method paint(g=Graphics)                 -- called to repaint the window
  767.       maxx=size.width-1
  768.       maxy=size.height-1
  769.       loop y=0 to maxy
  770.         col=Color.getHSBColor(y/maxy, 1, 1)  -- select a colour
  771.         g.setColor(col)                      -- set it
  772.         g.drawLine(0, y, maxx, y)            -- and fill a slice
  773.       end y
  774.  
  775. In this example, the variable 'col' will have type 'Color', and the
  776. three arguments to the method 'getHSBColor' will all automatically be
  777. converted to type 'float'.  As no overflows are possible in this
  778. particular example, 'options binary' may be added to the top of the
  779. program with no other changes being necessary.
  780.  
  781.  
  782. Summary and Information Sources
  783. """""""""""""""""""""""""""""""
  784. The NetRexx language, as you will have seen, allows the writing of
  785. programs for the Java environment with a minimum of overhead and
  786. 'boilerplate syntax'; using NetRexx for writing Java classes could
  787. increase your productivity by 30% or more.
  788.  
  789. Further, by simplifying the variety of numeric and string types of Java
  790. down to a single class that follows the rules of Rexx strings,
  791. programming is greatly simplified.  Where necessary, however, full
  792. access to all Java types and classes is available.
  793.  
  794. Other examples are available, including both stand-alone applications
  795. and samples of applets for Java-enabled browsers (for example, an applet
  796. that plays an audio clip, and another that displays the time in
  797. English).  You can find these from the NetRexx web pages, at
  798.  
  799.   http://www2.hursley.ibm.com/netrexx/
  800.  
  801. Also at that location, you'll find a more in-depth treatment of the
  802. language, and downloadable packages containing the NetRexx software and
  803. documentation.  The software should run on any platform that supports
  804. the Java Development Kit.
  805.