Menu

#680 Allow mulitline cascading messages

None
unread
nobody
None
none
1
2016-11-24
2016-11-19
No

If there is a large amount of cascading messages, it is natural to split them over lines.

Currently it is necessary in ooRexx to split the statement and supply trailing continuation characters (dash or comma).

*This would not be necessary, if ooRexx also allows the implicit continuation of a statement, if the first token on the next non-blank line is a tilde or a double tilde! *

This would allow one to write (artificial example) the statement
o~msg1~msg2(arg1,arg2,arg3)~msg3(a1,,a3)~~anotherMsg~~yetAnotherMsg(argument1,argument2)~~msga~msgb~msgc(a,b,c)

instead as:

        o~msg1
         ~msg2(arg1,arg2,arg3)
         ~msg3(a1,,a3)
         ~~anotherMsg
         ~~yetAnotherMsg(argument1,argument2)
         ~~msga
         ~msgb
         ~msgc(a,b,c)

As the parser is reading the entire file it would be possible to ease breaking
up cascading messages without forcing in this context a trailing continuation
character.

Currently one only would be able to break cascading messages over multiple lines
by coding, e.g.

        o~msg1,
         ~msg2(arg1,arg2,arg3),
         ~msg3(a1,,a3),
         ~~anotherMsg,
         ~~yetAnotherMsg(argument1,argument2)-
         ~~msga-
         ~msgb-
         ~msgc(a,b,c)

Comparing both versions of splitting cascading messages over multiple lines, I
think the latter version is more cumbersome for the programmer, but also more
difficult to read.

Related

Feature Requests: #680

Discussion

  • Anonymous

    Anonymous - 2016-11-19

    Whilst I agree with Rony that it is cumbersome to have to provide the continuation characters and more difficult to read, I feel that consistency is important.

    I think it is correct to say that In rexx continuation characters are always required when clauses are split. The only exception being multiline comments.

    There are other places where an implied continuation character would be usefull, for instance within the argument calls to a function, routine, or method

    I quite often code

       ret = method1( argument1 -
                    , argument2 -
                    , argument3 )
    

    for readability and entering that would also benefit from auto-continuation, but I recognise that having exceptions like this has a cost in terms of syntax consistency.

    I'm not voting this proposal down, but pointing out that there is a drawback to be weighed in the balance.

    Jon

    PS: The code sample above lines up in the sourceforge preview, but I think will be unaligned in the mailing of any who are following this list.

     
  • LesK

    LesK - 2016-11-19

    I agree with Jon, with more weight given to syntax consistency. Plus, saving one continuation
    character hardly seems worth the effort of Development, what with test cases and all else.

     
  • Rony G. Flatscher

    Well, the syntax consistency remains in place, as this RFE does not suggest an exception, rather it suggests an additional rule for future versions of ooRexx that help the programmers to forgo the line continuation character in the sole case of cascading messages.

    No existing code nor test cases etc. would have to be changed.

    Cascading messages become more and more common and for better legibility programming languages like C++, Java, C#, Javascript etc. split them up over multiple lines using indentation to line them up. It has become commong, that five, ten (sometimes even more) cascading invocations get coded in those languages. This is possible in those languages, because they define the end of such statements by the semi-colon, which is a mandatory token there.

    This trailing semi-colon was forgone by Rexx (and some other languages) to ease programming. This "saves one ... character" and it was deemed to be worth the effort all along! And it has been appreciated by many Rexx programmers to not have been enforced to write the semi-colon to end a statement.

    Rexx implies a semi-colon by a simple rule: if a semi-colon is missing, then the interpreter adds it at the end of a line. Should the programmer see a need to split a statement over multiple lines then he must supply a trailing comma or a trailing dash to indicate that the statement continues. Judging from many Rexx programs over the years, this possibilty has not been employed very heavily in the past, so the need for this has never been very high.

    Now contrast this to the way modern object-oriented languages get employed by programmers who have started to using multi-line statements more and more heavily. There are quite a few programming patterns that encourage this style of programming which is seen to be powerful and easy to grasp. Cascading function invocations are being employed more and more, distributing them for better legibility over many (sometimes many, many) lines.

    For BSF4ooRexx, but also for the new .Net support there, transcribing nutshell examples written in Java or C# to ooRexx is currently only possible, if using the continuation character, which barely have been used in classic Rexx. This forces one to add either a dash or a comma as the last character, which does not feel "natural" seeing how Java or C# are able to easily spread out their cascading of functions.

    Take the C++ example from https://en.wikipedia.org/wiki/Fluent_interface:

        FluentGlutApp(argc, argv)
                 .withDoubleBuffer()
                 .withRGBA()
                 .withAlpha()
                 .withDepth()
                 .at(200, 200).across(500, 500)
                 .named("My OpenGL/GLUT App")
                 .create();
    

    translated to ooRexx:

    FluentGlutApp~new(argc, argv) -
            ~withDoubleBuffer() -
            ~withRGBA() , 
            ~withAlpha() -
            ~withDepth() ,
            ~at(200, 200) , 
            ~across(500, 500) - 
            ~named("My OpenGL/GLUT App") - 
            ~create
    

    Show these two snippets to a C++, a Java, a C# programmer and ask them which version seems to be easier (more natural). It will be clear that they rightfully point at the C++ version.


    This RFE requets an additional rule for statement continuation in ooRexx only for taking advantage of cascading messages:
    if there is no semi-colon at the end of line and there is a trailing dash or comma, then the statement is continued on the next line,
    if there is no semi-colon at the ond of line and the next (non-blank) line starts out with a tilde (~) [or double-tilde (~~)] then regard the next line to be a continuation of the statement,
    * otherwise imply a semi-colon at the end of line

    Therefore this RFE would allow a 1:1 translation of cascading invocations in Java and .NET to ooRexx' cascading messages, allowing one to write instead:

    FluentGlutApp~new(argc, argv) 
            ~withDoubleBuffer() 
            ~withRGBA()  
            ~withAlpha() 
            ~withDepth() 
            ~at(200, 200)  
            ~across(500, 500) 
            ~named("My OpenGL/GLUT App")
            ~create
    

    And taking advantage of another ooRexx feature, that if a message carries no arguments one can forgo the parantheses:

    FluentGlutApp~new(argc, argv) 
            ~withDoubleBuffer 
            ~withRGBA  
            ~withAlpha
            ~withDepth
            ~at(200, 200)  
            ~across(500, 500) 
            ~named("My OpenGL/GLUT App")
            ~create
    

    The latter version being even a nice simplification over the C++ version, that is easier legible.

     
  • LesK

    LesK - 2016-11-21

    I didn't imply that *existing* code or test cases would have to change, but obviously new test cases would have to be generated, as well as new documentation and perhaps
    changes to existing docs, where appropriate.

    Your arguments are certainly compelling, but I fear that the changes necessary for ooRexx to
    look-ahead to the next source line would be a major impact.

     
    • Jon Wolfers

      Jon Wolfers - 2016-11-22

      Les,

      When you say major impact, do you mean would require a lot of development,
      or would have an impact on interpret-time performance? If the latter, I'd
      value technical opinions on that. It might increase tokenisation time at
      start-up, but is that even noticeable. I have some quite large scripts,
      tokenised each time they are run and never notice any lag at all. Are we
      talking about adding milliseconds or microseconds? It would be interesting
      to have an informed opinion as the scan ahead would have to be done for
      every line of every script whether or not they took advantage of this
      feature.

      Although you might be correct, I notice this comment in the parser:
      // multiple line case...sigh.

      Jon

      On 21 November 2016 at 22:47, LesK vmrexx@users.sf.net wrote:

      I didn't imply that existing code or test cases would have to change,
      but obviously new test cases would have to be generated, as well as new
      documentation and perhaps
      changes to existing docs, where appropriate.

      Your arguments are certainly compelling, but I fear that the changes
      necessary for ooRexx to
      look-ahead to the next source line would be a major impact.


      Status: unread
      Milestone: None
      Created: Sat Nov 19, 2016 03:58 PM UTC by Rony G. Flatscher
      Last Updated: Mon Nov 21, 2016 11:59 AM UTC
      Owner: nobody

      If there is a large amount of cascading messages, it is natural to split
      them over lines.

      Currently it is necessary in ooRexx to split the statement and supply
      trailing continuation characters (dash or comma).

      *This would not be necessary, if ooRexx also allows the implicit
      continuation of a statement, if the first token on the next non-blank line
      is a tilde or a double tilde! *

      This would allow one to write (artificial example) the statement
      o~msg1~msg2(arg1,arg2,arg3)~msg3(a1,,a3)~~anotherMsg~~
      yetAnotherMsg(argument1,argument2)~~msga~msgb~msgc(a,b,c)

      instead as:

          o~msg1
           ~msg2(arg1,arg2,arg3)
           ~msg3(a1,,a3)
           ~~anotherMsg
           ~~yetAnotherMsg(argument1,argument2)
           ~~msga
           ~msgb
           ~msgc(a,b,c)
      

      As the parser is reading the entire file it would be possible to ease
      breaking
      up cascading messages without forcing in this context a trailing
      continuation
      character.

      Currently one only would be able to break cascading messages over multiple
      lines
      by coding, e.g.

          o~msg1,
           ~msg2(arg1,arg2,arg3),
           ~msg3(a1,,a3),
           ~~anotherMsg,
           ~~yetAnotherMsg(argument1,argument2)-
           ~~msga-
           ~msgb-
           ~msgc(a,b,c)
      

      Comparing both versions of splitting cascading messages over multiple
      lines, I
      think the latter version is more cumbersome for the programmer, but also
      more
      difficult to read.


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/oorexx/feature-requests/680/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       

      Related

      Feature Requests: #680

  • Gil Barmwater

    Gil Barmwater - 2016-11-22

    I would like to second the importance of consistency. If we allow this "additional rule" for the ~/~~ operators, what is to prevent a request for also allowing it for other operators, say ||, to ease construction of very long strings?
    It seems to me that Mike made the choice to imply semi-colons by line-end rather than requiring them as in C, Java, etc. This choice means those languages don't have to indicate continuation while Rexx does. Adding this "additional rule" mixes those two paradigms which, I feel, is a bad idea.
    Gil B.

     
  • Rony G. Flatscher

    Consistency is not jeopardized at all. The rule for the RFE is simple and straight forward: "a statement can be continued, if either the last character on the line is a dash (or a comma) or the first token on the next line is a message operator". It can't possibly be simpler and alleviates a problem for ooRexx that has become more and more cumbersome for Rexx programmers.

    As I have been in the midst of creating nutshell examples for a student to create (totally portable) GUIs with JavaFx (part of Java since Java 1.7/7) and added (with a lot, a lot of effort) specific support to BSF4ooRexx to ease their task as much as possible, there are first "real-ooRexx" examples that demonstrate the problem (that has not been there in the past):

    /* rgf, 2016-11-19
       "stand-alone" (fxml-less) version of the fxml_02 application
    
    */
    
    .local~my.fx=.directory~new   -- to contain objects for easying the coupling of the different parts of this application
    .my.fx~rexxStarted=.dateTime~new~string   -- save the date and time this program started
    
    resources="fxml_02"    -- location of our resources (css, properties files, images)
       -- forward slashes ("WWW convention") suffice for both, Unix and Windows systems
    .my.fx~properties=resources || "/FXML_02"         -- Properties base file name
    .my.fx~appIcon   =resources || "/oorexx_032.png"  -- application icon
    .my.fx~bkgPicture=resources || "/bsf4oorexx_032.png" -- background picture for AnchorPane
    .my.fx~styleSheet=resources || "/fxml_02.css"     -- stylesheet to use
    
    parse arg locale                 -- parse command line arguments, if any
    if locale="" then locale="en"    -- default to English
    jLocale=.bsf~new("java.util.Locale", locale) -- get Locale object
       -- let ResourceBundle choose which properties file to load and use:
    .my.fx~resourceBundle=bsf.importClass("java.util.ResourceBundle")~getBundle(resources"/FXML_02", jLocale)
    
       -- create Rexx object that will control the FXML set up
    rexxHandler=.RexxAppHandler~new
    
       -- instantiate the abstract JavaFX class, the abstract "start" method will be served by rexxHandler
    rxApp=BSFCreateRexxProxy(rexxHandler, ,"javafx.application.Application")
    
       -- launch the application, invoke "start" and then stay up until the application closes
    rxApp~launch(rxApp~getClass, .nil)  -- cf. <http://www.dreamchain.com/javafx-and-groovy-exception/> or <http://stackoverflow.com/questions/16636883/javafx-anonymous-application-class>, etc.
    
    ::requires "BSF.CLS"    -- get Java support
    
    ::class RexxAppHandler  -- the Rexx handler for javafx.application.Application
    
    ::method start          -- will be called by JavaFX, allows to setup everything
      use arg primaryStage
    
      primaryStage~setTitle("Hello JavaFX from ooRexx!")  -- we could use primaryStage~title="..." instead!
    
      colorClz=bsf.loadClass("javafx.scene.paint.Color")           -- get access to the JavaFX colors
      cdClz=bsf.loadClass("javafx.scene.control.ContentDisplay")   -- get access to ContentDisplay constants (an Enum class)
      alClz=bsf.loadClass("javafx.geometry.Pos")                   -- get access to alignment constants (an Enum class)
      lblBuilderClz=bsf.loadClass("javafx.scene.control.LabelBuilder")   -- get the LabelBuilder class object
    
       -- a Rexx directory which contains all data needed in our event handler (cf. RexxButtonHandler Rexx class below)
      userData=.directory~new
      userData~count=1            -- each Button click will show and then increase this value
      userData~title="--> -> >"   -- a free form hint string
    
    /* AnchorPane definition in FXML, cf. "fxml_2/FXML_02_Document.fxml":
    
        <AnchorPane id="AnchorPane" fx:id="root"
             prefHeight="240.0" prefWidth="480.0"
             styleClass="root"
             stylesheets="@fxml_02.css"
             xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
    */
      root=.bsf~new("javafx.scene.layout.AnchorPane")   -- create the root node
      root~id="root"        -- treat Java field/property as if an ooRexx attribute
      root~prefHeight=240   -- treat Java field/property as if an ooRexx attribute
      root~prefWidth=480    -- treat Java field/property as if an ooRexx attribute
      root~getStyleSheets~add(.my.fx~styleSheet)
      rootChildren=root~getChildren  -- collection of javafx controls to manage
    
    -------------------------------------------------------------------
    /* Label definition in FXML, cf. "fxml_2/FXML_02_Document.fxml":
    
       <Label fx:id="labelRexxStarted" alignment="CENTER" layoutX="50.0" layoutY="26.0"
            minHeight="16" minWidth="69" prefHeight="16.0" prefWidth="380.0"
            styleClass="rexxInfo" stylesheets="@fxml_02.css"
            text="$rexxStarted" />
    */
          -- define the first Label
      lbl=.bsf~new("javafx.scene.control.Label")
      lbl~setId("rexxStarted")
      lbl~setAlignment(alClz~valueOf("CENTER"))  -- center align, alternatively: "alClz~CENTER"
      lbl~setLayoutX(50)
      lbl~setLayoutY(26)
      lbl~setMinHeight(16)
      lbl~setMinWidth(69)
      lbl~setPrefHeight(16)
      lbl~setPrefWidth(380)
      lbl~getStyleClass~add("rexxStarted") -- add the CSS style named ".rexxStarted" to this node
      lbl~setText(.my.fx~rexxStarted)
      rootChildren~add(lbl)       -- add this Label control
    
    -------------------------------------------------------------------
    /* Label definition in FXML, cf. "fxml_2/FXML_02_Document.fxml", code goes to RexxButtonHandler's 'handle':
    
            <Button fx:id="button" layoutX="210.0" layoutY="137.0" onAction=
               "
                       say ' ==&gt; ---&gt; arrived in button''s onAction-code ...'  ;
                       /*@showsource*/ /* the previous Rexx script annotation will cause this code to be shown in original and edited state */ ;
                       use arg slotDir /* this argument is always sent by BSF4ooRexx */ ;
                       /*@get('label')*/ /* the previous Rexx script annotation will incorporate the attribute 'label' as a local Rexx variable */ ;
                       say ' ... label~getText='pp(label~getText)  ;
                       say ' ... changing text in label to current date and time ...' ;
                       label~text=.dateTime~new~string             ;
                       say ' ... label~getText='pp(label~getText)  ;
                       say ' ... now invoking the public Rexx routine ''klickButtonAction''' ;
                       call klickButtonAction slotDir /* now process the event */;
               "
               text="%clickMe"
            />
    */
          -- define and add the Button
      btn=.bsf~new("javafx.scene.control.Button")
      btn~id="button"
      btn~layoutX=210       -- assign as if it was a Rexx attribute
      btn~layoutY=137       -- assign as if it was a Rexx attribute
      btn~text=.my.fx~resourceBundle~getString("clickMe") -- assign as if it was a Rexx attribute
          -- create a RexxButtonHandler, wrap it up as a Java RexxProxy implementing all methods of "javafx.event.EventHandler";
          -- supply the RexxDirectory "userData" as second argument, such that it gets returned via the appended slotDir argument
      bh=BSFCreateRexxProxy(.RexxButtonHandler~new, userData,"javafx.event.EventHandler")
      btn~setOnAction(bh)   -- let this instance's Java RexxProxy handle the event
      rootChildren~add(btn) -- add this Button control
    
    -------------------------------------------------------------------
    /* Label definition in FXML, cf. "fxml_2/FXML_02_Document.fxml":
    
            <Label fx:id="year" layoutX="50.0" layoutY="175.0" minHeight="16" minWidth="20" style="-fx-background-color: palegoldenrod;" text="%year" />
    */
       -- now using a LabelBuilder instead; NOTE: no "set" prefix, just use the property/field names;
       -- cf. <http://blog.netopyr.com/2012/01/24/advantages-of-javafx-builders/>
      lblBuilder=lblBuilderClz~create
      lblBuilder   ~id("year") -
                   ~textFill(colorClz~BLUE) -
                   ~layoutX(50) -
                   ~layoutY(175) -
                   ~minHeight(16) -
                   ~minWidth(20) -
                   ~style("-fx-background-color: palegoldenrod;") -
                   ~text(.my.fx~resourceBundle~getString("year"))
      lbl=lblBuilder~build  -- now create the new Label from this data
      rootChildren~add(lbl) -- add this Label control
    
    -------------------------------------------------------------------
    /* Label definition in FXML, cf. "fxml_2/FXML_02_Document.fxml":
    
            <Label fx:id="label" layoutX="95.0" layoutY="175.0" minHeight="16" minWidth="49" prefHeight="16.0" prefWidth="335.0" style="-fx-background-color: honeydew;" />
    */
       lblBuilder  ~id("label") ,    /* skipping ~textFill(colorClz~BLUE) as already set */
                   ~layoutX(95) ,
                   ~layoutY(175) ,   /* skipping ~minHeight(16) as already set */
                   ~minWidth(49) ,
                   ~prefHeight(16) ,
                   ~prefWidth(335),
                   ~style("-fx-background-color: honeydew;") ,  --
                   ~text("")
    
      lbl=lblBuilder~build  -- now create the new Label from this data
      rootChildren~add(lbl) -- add this Label control
      userData~label=lbl    -- put it into our userData Rexx directory
    
    -------------------------------------------------------------------
    /* Label definition in FXML, cf. "fxml_2/FXML_02_Document.fxml":
    
            <Label fx:id="labelRexxInfo" alignment="CENTER" layoutX="50.0" layoutY="200.0" minHeight="16.0" minWidth="49.0" prefHeight="16.0" prefWidth="380.0" style="-fx-background-color: skyblue; -fx-cursor: wait; -fx-font-family: serif; -fx-font-weight: lighter;" text="${rexxInfo}" />
    */
       lblBuilder  ~id("labelRexxInfo") ,  /* skipping ~textFill(colorClz~BLUE) as already set */
                   ~alignment(alClz~CENTER) -
                   ~layoutX(50) ,
                   ~layoutY(200) -   /* skipping ~minHeight(16) as already set */
                   ~minWidth(49) ,   /* skipping ~prefHeight(16) as already set */
                   ~prefWidth(380) - /* skipping ~text("") as already set      */
                   ~style("-fx-background-color: skyblue; -fx-cursor: wait; -fx-font-family: serif; -fx-font-weight: lighter;")
    
      lbl=lblBuilder~build  -- now create the new Label from this data
      rootChildren~add(lbl) -- add this Label control
      userData~rexxInfo=lbl -- put it into our userData Rexx directory
    
    -------------------------------------------------------------------
          -- put the scene on the stage (using AnchorPane's preferred height and width)
      primaryStage~setScene(.bsf~new("javafx.scene.Scene", root))
      img=.bsf~new("javafx.scene.image.Image", .my.fx~appIcon)
      primaryStage~getIcons~add(img)                       -- set application icon
      primaryStage~show
    
       -- Rexx class which handles the button presses
    ::class RexxButtonHandler
    
    ::method handle      -- will be invoked by the Java side
      use arg event, slotDir   -- the last argument will always be added by BSF4ooRexx
      say " ==> ---> arrived in button's RexxButtonHandler's 'handle' method ..."
      slotDir=arg(arg())          -- get last argument, will always be added by BSF4ooRexx
      userData=slotDir~userData   -- fetch the Rexx directory we supplied at button event handler creation time
       -- get values we want to work with
      rexxInfo=userData~rexxInfo  -- get the rexxInfo Label    ^
      count   =userData~count     -- get the current value of 'count'
      title   =userData~title     -- get the value of 'title'
      label   =userData~label     -- get the Label with the id "label"
    
      say ' ... label~getText='pp(label~getText)
      say ' ... changing text in label to current date and time ...'
      label~text=.dateTime~new~string
      say ' ... label~getText='pp(label~getText)
    
       -- as this version does not use the javax.script infrastructure there is
       -- no "ScriptContext" from javax.script available to us; "fxml_02" by
       -- contrast will access it and display its content on each invocation
    
       -- using the FXMLLoader we could have it update this Label
      rexxInfo~text="Updated from RexxButtonHandler's 'handle' method."
      if count//2=0 then rexxInfo~text=rexxInfo~text~reverse -- if even, reverse the current text
      userData~count+=1           -- increment value of 'count'
    
        -- access the "label" JavaFX Label, change its text
      label~setText(title .dateTime~new~string "(count #" count")")
    
      say " <== <--- returning from RexxButtonHandler's 'handle' method."
      say
    

    The reason for these cascading messages is to ease coding for the programmers. The programmers should not have to type over and over the receiver, so the Java people came up with clever ideas and have been applying programming patterns to the JavaFX library.

    As Rexx (and ooRexx) has been shining because of its "human-centricness", new challenges should be addressed.

    Allowing this RFE will remove the need for placing trailing dashes/commas in the case that statement continuation is obvious anyway as the next line starts with a message operator!

    Owing to the Rexx design principle of "human-centricness" this proposal was created. It eases programming a lot, on can safely forgo typing (in this context totatally unneded) trailing dashes or commas, which looks actually quite awkward if you go thru the above code.

    This RFE would introduce the option to forgo the current need to add trailing commas/dashes. I am quite confident such this option will be taken advantage of immediately after it gets available!


    Besides, ooRexx has already implemented/changed some long-standing behaviours in the context of messages (which have not existed at the time classic Rexx was conceived), in order to ease coding for the programmer and to make the code easier to read, i.e. easier to maintain.

    In classic Rexx, if you use a routine as a function, you must use parenthesis, if you want the routine invocation to be replaced by the function value, even in the case that one has no arguments to supply to the routine!

    E.g. a one-liner snippet that extracts the last three characters in a string:

    a="This is it!"
    say reverse(substr(reverse(a),1,3))
    

    In ooRexx you could code this with messages like this:

    a="This is it!"
    say a~reverse()~substr(1,3)~reverse()
    

    Now, in the case of messages (which will cause the appropriate method routines to be invoked by the receiving object) there is an option breaking ;) the function-invocation rule in as it is allowed to forgo the parentheses in the case that they carry no arguments!

    So the above message version can be (and is often, because simpler and easier to read) rewritten as:

    a="This is it!"
    say a~reverse~substr(1,3)~reverse
    

    That was a very clever and very human-centric (optional!) innovation that is being taken advantage of by all my students, because it is easier to write and easier to read (and to maintain because of that)!

     
  • LesK

    LesK - 2016-11-24

    ~reverse() vs. ~reverse is a fine example of melding Classic and Object Rexx so either type of
    programmer can work with what they are most familiar with, even though they *both* might think that their 'rules' are being broken. It would also seem to answer Gil's argument.

    As a VM Dinosaur, my natural tendency is to respect the Early Rexx history when Mike was first
    developing Rex on paper and then distributing Alpha, Beta and Tools versions throughout IBM via VNET. Finally resulting in Rexx becoming part of the VM product.

    But now we have Open Object Rexx and my exposure to it, as both an observer and sometimes
    author, leads to the realization that the Community can provide a faster and better feedback
    cycle than IBM's formal Development cycle. Not as fast as the Rexx Forum we had back in the old days, but still interactive and responsive enough.

    Pending furthe analysis of the effort & impact to the code, docs and test cases,
    I support Rony's RFE.

     

Anonymous
Anonymous

Add attachments
Cancel