Problem solve Get help with specific problems with your technologies, process and projects.

Free-format RPG only half-way free

Columnist Steve Croy points out that free-format RPG isn't quite as restrictive as fixed-format RPG, but it isn't totally free either. The implementation stops short of making RPG a free-format language in the nature of Java, C or HTML.

As Martha Stewart can tell you, half-way free isn't the same thing as being free. An ankle bracelet and house arrest is not the same as being in prison, but it's not exactly free either. (Not to mention it's very difficult to accessorize that darn ankle bracelet!) That's the problem with free-format RPG. It isn't quite as restrictive as fixed-format RPG, but it isn't totally free either.

The concept of free-format RPG isn't something new. I recall Paul Conte writing articles about it many years ago and offering up his concept of what free-format RPG should be. In retrospect, it was an idea ahead of its time. After considerable water under the bridge, IBM finally got around to presenting its interpretation of free-format RPG. However, IBM and I happen to disagree on what constitutes free-format.

I don't think IBM's version of free-format RPG was what Paul Conte envisioned, and I have read comments from Bob Cozzi and other noted iSeries experts that suggest that while IBM's implementation of free-format RPG is a step forward, it is far from perfect. From my own personal perspective (What do I know? I'm just a programmer.) IBM has not actually produced free-format RPG. They deserve credit for trying, but the implementation stops short of making RPG a free-format language in the nature of Java, C or HTML. (COBOL? Sorry, COBOL statements are bound by paragraph A and paragraph B, so COBOL does have limitations not inherent in a true free-format language.)

0157.00       IF recordFound                               ;
0158.00          IF billflag <> '*BILL' OR milesbilled = 0 ; 
0159.00             deleteRecord()                         ;
0160.00          ELSE                                      ;
0161.00             setMiles( milesbilled )                ;
0162.00             setRate( mi_rate )                     ;
0163.00             setBasis( mi_basis )                   ;
0164.00             updateRecord()                         ;
0165.00          ENDIF                                     ;
0166.00       ENDIF                                        ;

One of the high points of free-format RPG is the ability to make the code easier to read and interpret. I do like the fact I can write self-documenting code that reads almost like English syntax with free-format code, but I am frustrated by the quirks and fixed limitations of supposedly free-format code. With IBM's compiler, I cannot begin a statement before column 7 or extend beyond column 80. After following the rules of indentation, once nested several levels, I quickly run out of space for writing expressions to the right of an assignment (=, <, >, etc.) symbol.

The 80 column limit, by the way, is not due to any limitation on the part of the SEU editor. Though not as flexible as GUI code editors, SEU can, and does, support text entry up to 240 columns long. When creating CGI applications there have been times when rather than using DreamWeaver or FrontPage, I have used SEU as an editor to enter HTML and Net.Data script code. (Then, after editing the source, I used the command CPYTOSTMF to move the source to the IFS.)

When I'm creating quick and dirty HTML on the fly with a simple text editor such as MS notepad, I can start entering tags in column 1. And if I were silly enough, I could type the entire document on the same line. That is free-format. HTML documents may contain embedded script and, though delimited by a script tag <script type="text/JavaScript">, JavaScript instructions do not have to start past column 7 and can extend well beyond column 80.

It is also quite common to find SQL embedded in CGI script, Net.Data or otherwise. And those SQL statements are free-format in nature. Yet when I embed SQL within RPG to enter free-format SQL statements, I have to exit free-format RPG. I'm quite sure I'm not the only one who has noticed a certain contradiction in exiting a free-format language in order to enter a free-format statement. Rather than hopping in and out of free-format code, which not only looks ugly but gets confusing, I have taken to moving all SQL statements to subroutines or subprocedures and using EXSR or procedure calls to invoke SQL operations.

On another note, free-format may be easier to read, but it does not necessarily follow that it is also easier to use. BITON and BITOFF fixed-format instructions are much simpler to use than the bitwise BIFs provided in free-format code. Free-format RPG still does not have a single operation equivalent of a fixed-format move statement. Free-format syntax does not support MOVEA or CASxx.

Why IBM chose to support the in-line case (SELECT) structure and not CASxx isn't exactly clear. It does not seem like it would be any more difficult to create a case structure similar to Java's switch to support CASxx than to create the in-line case structure of the SELECT.

public class SwitchDemo {
    public static void main(String[] args) {

        int month = 8;
        switch (month) {
            case 1:  System.out.println("January"); break;
            case 2:  System.out.println("February"); break;
            case 3:  System.out.println("March"); break;
            case 4:  System.out.println("April"); break;
            case 5:  System.out.println("May"); break;
            case 6:  System.out.println("June"); break;
            case 7:  System.out.println("July"); break;
            case 8:  System.out.println("August"); break;
            case 9:  System.out.println("September"); break;
            case 10: System.out.println("October"); break;
            case 11: System.out.println("November"); break;
            case 12: System.out.println("December"); break;
            default: System.out.println("Month error!"); break;

(Code from Sun's Java Tutorial:

IBM still supports the use of subroutines within RPG. Though the CASxx operation is not supported in free syntax, EXSR certainly is. There is a certain irony that surfaces when considering that an Old Program Model (OPM ) construct, a subroutine, may be defined without breaking out of free-format syntax, but that defining the Integrated Language Environment (ILE) construct of a subprocedure requires exiting free-format RPG. (P,B, and E specs are fixed-format.)

Referencing the Java code sample, note the inclusion of the break statement on the same line as the print line instruction. Java and JavaScript language syntax allows multiple instructions per line, separated by a semicolon. IBM's implementation of free-format RPG does not support that feature. Admittedly, this is not a major issue. However, in certain instances, such as the switch example above, it makes perfect sense to put the related instructions on the same line.

The inconsistent melding of free-format and fixed-format instructions of the program source also spills over into compiler directives. The RPG compiler demonstrates several quirks relative to the unresolved idiosyncrasies of free-format/fixed format coexistence. For example, the /copy directive makes no concession to the /free directive. The /copy compiler directive assumes the copybook member to be in fixed-format code. So, free-format source code within a copybook must be enclosed within /free in order to be presented correctly for compilation, even if the /copy statement is nested within /free.

To illustrate: The following copy instruction references a source member DTEST_1. Note that the copy follows a /free directive. But for the program to compile correctly, the copybook source must include the /free and /end-free directives. Without the /free directives in the copybook source member, the compile will fail, since, implicitly, the source copied is assumed to be fixed-format RPG, thus generating syntax errors.

Copy directive

0037.00  /free            
0039.00  /copy DTEST_1    

Copybook DTEST_1

0002.00  /free                                          
0003.00     TimeOfDay = %dec(%char(%time():*hms0):6:0); 
0004.00     DateToday = %dec(%char(%date():*iso0):8:0); 
0005.00     DateYMD   = %dec(%char(%date():*ymd0):8:0); 
0006.00     JulDate = %dec(%char(%date():*jul0):5:0);   
0007.00  /end-free                                      

Conversely, some free-format features are recognized, whether they appear within /free or not. The double slash (//) will be recognized as a free-format comment regardless if it is preceded by the /free directive or not. (That is, as long as the comment begins past column 6!) The following code is from a source member that compiles just fine. The code is fixed-format RPG. There is no /free directive in the source, yet the compiler recognizes line 129 for what it is -- a free-format comment entry.

0125.00 C                   IF        MSGFLG = #YES                  
0126.00 C                   EXSR      @WRMSG                         
0127.00 C                   ENDIF                                    
0129.00    // Display subfile, test for EOJ, and function requested. 
0131.00 C                   IF        SCNIND = *ON                   
0132.00 C                   EXSR      @PSCSR                         
0133.00 C                   ENDIF                                    

IBM's implementation of free-format RPG comes tantalizingly close, but just does not reach far enough to qualify as truly, free-format programming language. It still has an ankle bracelet that keeps it tethered to its fixed-format roots. The developers have obviously put a lot of effort into the product, and the results show it. Though it may not be what we wanted, it's not bad. As my daddy used to say, "It ain't what you want that makes you fat; it's what you get." What we got from IBM was a compiler that supports something that isn't quite fixed-format, yet isn't quite free-format. I can work with that, for now.

About the author: Steve Croy is a programmer at USXpress Enterprises Inc. in Chattanooga, Tenn.

Dig Deeper on RPG iSeries programming