Wednesday, March 12, 2014

Mixing it up with RPG all free

ctl-opt dcl-f dcl-s dcl-ds

With the new RPG all free we have been liberated from using the fixed format specifications. With the new definition operations we can intermingle “specifications”, within reason. I decided to see what I could do with a simple program that has one input file and a display file, which contains a subfile. In this post I will explain what I have found, some of it may be obvious to some but not to others.

Before our liberation specifications have had to be entered in a specific order. For example in RPGLE:

  • Control/Header (H)
  • File (F)
  • Definition (D)
  • Input (I), if needed
  • Calculation (C)
  • Output (O), if needed
  • Procedure (P)

Below is my example program’s code with the fixed format specifications in order:

01 H option(*nodebugio:*srcstmt)

02 FTESTDF    CF   E             WORKSTN indds(IndDs)
03 F                                       sfile(SFL01:Z1RRN)
04 FTESTPF    IF   E           K DISK

05 D PgmDs         ESDS                  extname(RPG4DS) qualified

06 D IndDs           DS
    * Function keys
07 D   Exit                  3      3N
08 D   Refresh               5      5N
    * Subfile indicators
09 D   Sfl1CtlDsp           30     30N
10 D   Sfl1Dsp              31     31N

11 D i               S                   like(Z1RRN)
12 D wkSfl1Inz       S               N   inz(*on)
    /free
13     Z1SCREEN = %trimr(PgmDs.ProcNme) + '-1' ;

This is the same using the new definition operations, but keeping the definitions in the same places as the equivalent fixed format would be:

01    ctl-opt option(*nodebugio:*srcstmt) ;

02    dcl-f TESTDF workstn indds(IndDs) sfile(SFL01:Z1RRN) ;
03    dcl-f TESTPF usage(*input) keyed ;

04    dcl-ds PgmDs
05       extname('RPG4DS') psds qualified
06    end-ds ;

07    dcl-ds IndDs qualified ;
        // Function keys
08       Exit ind pos(3) ;
09       Refresh ind pos(5) ;
10      // Subfile indicators
11       Sfl1CtlDsp ind pos(30) ;
12       Sfl1Dsp ind pos(31) ;
13    end-ds ;

14    dcl-s i like(Z1RRN) ;
15    dcl-s wkSfl1Inz ind inz(*on) ;

16    Z1SCREEN = %trimr(PgmDs.ProcNme) + '-1' ;

So let’s starting mixing this RPG code up. There is no reason why I cannot change/write the code to look like below:

01    ctl-opt option(*nodebugio:*srcstmt) ;

02    dcl-ds PgmDs
03       extname('RPG4DS') psds qualified
04    end-ds ;

05    dcl-f TESTDF workstn indds(IndDs) sfile(SFL01:Z1RRN) ;

06    dcl-ds IndDs qualified ;
        // Function keys
07       Exit ind pos(3) ;
09       Refresh ind pos(5) ;
        // Subfile indicators
10       Sfl1CtlDsp ind pos(30) ;
11       Sfl1Dsp ind pos(31) ;
12    end-ds ;

13    dcl-s i like(Z1RRN) ;
14    dcl-s wkSfl1Inz ind inz(*on) ;

15    dcl-f TESTPF usage(*input) keyed ;

16    Z1SCREEN = %trimr(PgmDs.ProcNme) + '-1' ;

I have found that the CTL-OPT does have to be the first line. My attempts to move it elsewhere caused a compile error, RNF0257. I am OK with that.

As the program data structure, PSDS, is for the entire program I wanted to put it next, lines 2-4.

Next up the declaration for the display file, line 5. Then the indicator data structure, IndDs, lines 6-13. When I tried moving the data structure above the declaration for the display file I received a compile error, RNF0203, that explained the data structure had to be defined after the file.

I have defined the two standalone variables, lines 14 and 15, before defining the last file, TESTPF.

I cannot move lines from the “calculation specification” expressions, for example line 13, amongst the declarations as the program will not compile.

If you decide to stay using fixed format you can still mix up the order of the specifications, as I show below:

01 H option(*nodebugio:*srcstmt)

02 D PgmDs         ESDS                  extname(RPG4DS) qualified

03 FTESTDF    CF   E             WORKSTN indds(IndDs)
04 F                                       sfile(SFL01:Z1RRN)

05 D IndDs           DS
    * Function keys
06 D   Exit                  3      3N
07 D   Refresh               5      5N
    * Subfile indicators
08 D   Sfl1CtlDsp           30     30N
09 D   Sfl1Dsp              31     31N

10 D i               S                   like(Z1RRN)
11 D wkSfl1Inz       S               N   inz(*on)

12 FTESTPF    IF   E           K DISK

13    Z1SCREEN = %trimr(PgmDs.ProcNme) + '-1' ;

I need to think carefully of how I am going to use this to make sure that whatever approach I adopt to order my definitions is not confusing to my colleagues.

 

I am old enough to have worked with some other specifications that were found in RPGIII and RPGII:

  • Extension (E)
  • Line counter (L)
  • Telecommunications (T)

Have you worked with any others? If so what were they? And what was their function?

 

You should read my other posts introducing all free RPG:

25 comments:

  1. U specs for auto copy come to mind.

    ReplyDelete
  2. I have mixed feelings about this, even though I am an avid /free-er. I certainly don't want to resist change, but I also don't want to change for the sake of change, especially if we are losing more than we are gaining.

    It is very easy to take in the "strategy" of a program by scanning the F-specs and D-specs and this process is far quicker if one can employ "spacial senses" as well as just reading skills. I really think that mixing it up might be a huge mistake - those up front specs give you an idea of what is going on in the program and some context for a more detailed study of the code that follows.

    Also, at this point, for me, it still seems to be far quicker and accurate to parse and take in fixed format F and D specs than free format specs . I also find that it is easier to miss something important in the D-specs, when quickly parsing the free-format variety.

    For instance, I completely missed one of the Definition specs on the first take of your free-form rework example and only noticed it when I came back and was cross-checking carefully with your original code. (I admit that this may pass with familiarity.)

    It is possible that free-form F-specs might be easier for novice RPG programmers (who don't yet have those column positions engrained in the brains) to understand, but I am pretty sure that it is far easier to take in at a glance whether a file is being updated, for instance, in fixed-form. (By the way, is there a missing semi-colon on line 5?)

    Now... similar thoughts may have gone through my head, the first time I considered free-form calcs (for instance, I seem to remember whining "but in fixed form, you can just scan the RESULT column to see fields that might get changed").

    However, there were clear cut advantages to free-form calcs: indentation offered the ability to use spacial significance to help understand the overall structure and flow of the program. That was a huge leap forward and far outwieghed the loss of any fixed-form advantages.

    At this point, I cannot see any significant benefits of setting F-specs and D-specs free and, as well as the loss of "spacial significance", it is also to imagine it being possible for a spec to become verbose enough to start reminding us really old guys of Cobol.

    I think that we should take this next leap to freedom cautiously and be careful that we do lose more than we gain. But this is a debate - my mind is still open.

    ReplyDelete
    Replies
    1. > By the way, is there a missing semi-colon on line 5?

      As there are no subfields entered for this data structure, just the name of the external file, there is no semi colon on line 5.

      I could have coded it on just one line, but I think it is easier to understand as I have entered it.

      Delete
    2. Steve, the notion of getting a decent overview by scanning the F specs went out the window in the RPG III days on S/38. That's when we got CALL in RPG. At that moment, a programmer could CALL another RPG program, and that called program could do all sorts of updates to files not defined in the caller's F specs.

      The inaccuracy of scanning F specs got worse when we got embedded SQL; now an UPDATE, INSERT or DELETE could be anywhere in the code: none of which are hinted by the presence of F specs.

      For me, the final nail in the coffin was sub-procedures. It's all too easy to have a service program that does I/O for you, and a main program that doesn't seem to do any I/O because all it does is call sub-procedures.

      Our sense of tradition is strong, but the overwhelming advantages of fully free specs are hard to argue against. Modern languages are column-free. I'm glad RPG is now free too.

      Delete
    3. As one who has ALWAYS despised fixed format RPG - what column is that indicator in again? Oh - and indicator 50 meant what exactly? Which IF did that ELSE match up with? Yeah - fixed format was soooo much clearer and easier to read than free format.... NOT!

      RPG is now where it should've been decades ago. We haven't used punch cards in over 30 years... fixed format RPG needs to go the same place as those dinosaurs....



      Delete
    4. Rocky, you will get no argument from me about the significant leap forward in C-specs that /FREEdom brought us and I am no lover of indicators. I am ambivalent about F-specs. I am just healthily skeptical about whether we might be losing more than we are gaining where D-specs are concerned - I don't think you have to be particularly familiar with the column format to take in a fixed-form D-spec with a glance.

      Let's not allow our mutual hatred of fixed-form lead us to just throw it out on principle in all cases, when there might just be one form type where fixed form could still be the better solution.

      I want to keep an open mind until I have had some real experience of trying to dig into someone else's program that employs free-form D-specs before I finalize my decision.

      Delete
  3. I did not know that all of the H, F, and D specs can now be replaced with free. Now I won't be getting those annoying compile errors because I forgot to put free on or off.

    Most of my coding in RPG is embedded SQL anymore and it will be nice to not need to define data structures, variables, indicators, or files and then do the free on/off.

    ReplyDelete
    Replies
    1. I love the new format - the /free & /end-free statements were totally useless and extremely annoying. The only thing that is a nuisance is the DCL-S for stand alone variables but I get past that by just creating a data structure called STANDALONE.... and define all of these in that data structure....

      Delete
  4. Having to work with older versions of the operating system I still need the /free and /end-free commands.

    ReplyDelete
  5. Jaime Muñoz MuñozMarch 13, 2014 at 9:36 AM

    This great but is missing documentation on FREE. IBM manuals are bad.
    Recently we are installing Rational and editor has support write per code.
    I hope will be enough to move through this environment with guarantees ..!

    If you find documentation on RPG FREE, I hope you share

    ReplyDelete
    Replies
    1. An overview: https://www.ibm.com/developerworks/ibmi/library/i-ibmi-rpg-support/

      Read the 'What's New Since 7.1' section of the RPG manual: http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/books/sc092508a.pdf

      Delete
    2. http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_71/books/sc092508a.pdf

      This has all the info....

      Delete
    3. Buck and Rocky gave links to the same file. I am just going to make it clickable here

      Delete
  6. I like the new free-form syntax and look forward to installing the technology refresh and trying it. The main problem - we still use SEU, which will highlight the lines as errors. IBM is forcing us to move to Rational tooling.

    ReplyDelete
    Replies
    1. You can use SEU for the new all RPG free, just turn off "syntax checking" in SEU.

      If you do not know how to do that I explain here how its done.

      Yes, IBM does want us to move from SEU to RDi. I fear that they have not considered that many businesses will see it as an "extra unnecessary" expense and their developers will have to continue with SEU.

      Delete
    2. Thanks for the tip about turning SEU syntax checking off. I'll look forward to trying that. It's not that I view developer tools as an "unnecessary expense". We're willing to pay for ADTS, for example. I have a lot of experience with Windows-based IDEs. And we may eventually purchase RDI. But I'd prefer a thin-client interface for managing libraries, files, source members, and so forth.

      Delete
    3. Thanks for the tip :)

      Delete
  7. Buck - you make a great point that I had not considered. As well as your SQL point, I am also moving towards "Service CRUDs", so my scanning point is, indeed, a suspect one, especially for new applications using current modern architecture. I still am not convinced that D-specs, in particular,are easier to read, but, in the name of open-mindedness, I am prepared to accept that this might just be familiarity. Thanks for steering me back to objectivity with a solid factual argument and steering me away from giving in to my "back in the old days when I was young......" prejudices. :-)

    ReplyDelete
  8. Correct?

    /FREE
    IF VAR = 'S';
    /END-FREE
    C *IN50 IFEQ *ON
    C 'hello world' DSPLY
    C ENDIF
    /FREE
    ENDIF;
    /END-FREE

    ReplyDelete
    Replies
    1. With the version of RPG used in this post you no longer need the /FREE and /END-FREE operations.

      Delete
  9. Hi Simon,

    Thanks to your help Im making good progress with totally free :)
    Im stuck on something that I thought would have been simple though. I have a program where I want to do an update so I put a procedure in as follows:
    dcl-f MAILTXTL usage(*update) keyed ;
    chain ('TESTHT') MAILTXTL;
    TXVPFX = 'I_ALRT3';
    update PRSDET;

    However, it complains that "a result data structure is required for I/O to a qualified file" (*RNF7274)
    What is this referring to? do I simply declare the fields that are in it as a ds like so:
    dcl-ds Ds qualified dim(150) ;
    EMADD char(90) ;
    EMREF char(6) ;
    EMREG char(6) ;
    EMCDE char(3) ;
    end-ds ;
    and if this is the case, surely that's less efficient than the old style rpg free as the compiler was able to pull in the fields at compile time? and of course if you had tables with lots of fields the programs would become huge.

    James

    ReplyDelete
    Replies
    1. Have you read these two posts?

      Defining files in subprocedures

      Defining files in subprocedures, part 2

      These both give examples of coding the data structures needed when using files within a procedure.

      I have been reassured by IBM-ers that using data structures is more efficient for RPG's input and output buffers . There is only one "thing", the data structure, rather than many, the individual fields.

      Delete
    2. HI Simon,

      Thank you very much. Yes, that's exactly what I was looking. Superb :)

      Regards
      James

      Delete
    3. Thank you for the feedback, and I am glad that it helped.

      Delete

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.