IBM i > DEVELOPER > RPG

25 Years of RPG


With all the celebrations going on related to the 25th anniversary of IBM i coming up in June, we thought it would be interesting to take a look back at one very specific aspect of IBM i—RPG: the language of choice for the majority of IBM i shops. Of course, RPG existed a long time before June 1988, but we’re going to limit this discussion to the most recent 25 years.

Back In the Not-So-Good Old Days

Think back to the RPG we had in June 1988. At the time it didn’t seem so bad, but compared to where we are today, RPG/400 seems an ancient dialect. Of course, it’s a dialect that’s still available for use today. In fact, sadly some shops out there are still writing new code in RPG/400—for reasons that completely escape us!

In 1988, we had RPG/400, which was for the most part a renamed RPG III from the System/38. Perhaps its biggest enhancement over the S/38 version was the capability to embed SQL for database I/O as an alternative to the native I/O operation codes. Even that significant enhancement was barely utilized in the early days. Subsequently there were very few enhancements made to RPG/400 in the years before V3R1 of OS/400.

Then came the new RPG—called RPG IV by most, although IBM’s official name was a long-winded variant of ILE RPG. While this new language could be used as an ILE language, it was more often used as simply a better version of the RPG language—much better, as it turns out. Right off the bat in its first release, RPG IV had features that topped RPG/400, such as longer field names, mixed case source, expressions, date data types and a library of powerful built-in functions.

Then with each subsequent release of RPG IV, IBM added more and more enhancements. See the sidebar, “A Brief History of RPG IV.” Needless to say, when RPG IV came out, IBM put all its RPG development effort into it.

For those who, like us, happily left RPG/400 at the earliest opportunity, here’s a reminder of coding in the bad old days. A simple payroll tax calculation for an hourly employee looked like this (employees get time and a half for hour worked beyond the first 40):

C        HOURS     IFLE 40
C        HOURS     MULT RATE      PAY
C                  ELSE
C        RATE      MULT 40        PAY     72
C        HOURS     SUB  40        OTIME   30
C        RATE      MULT 1.5       OTRATE  94
C        OTRATE    MULT OTIME     OTPAY   72
C                  ADD  OTPAY     PAY
C                  END

Of course, this isn’t nearly as bad as some RPG/400 code; there’s not a single conditioning indicator in sight! Many versions of this kind of code would have used COMP and conditioning indicators in place of the IFLE type of code.

Below is today’s way to write that same logic.

                     
  If Hours <= 40;                     
   Pay = Hours * Rate;                  
  Else;                          
   Pay = (40 * Rate) + ((Hours - 40) * (Rate * 1.5));         
  EndIf; 

This is not just a fixed-form vs. free-form comparison. Likewise, the value of this version is not simply 5 lines of code vs. 9 lines of code. Readability is the true difference. Now it’s crystal clear that the purpose of this block of logic to calculate the value of Pay under two different conditions. Yes, the first code did the same thing, but it’s not nearly so obvious. Expressions allowed us to do away with three temporary work fields that clouded the ultimate purpose of the code.

Some of you may be thinking that we jumped a few years—and you’re right. This example jumped all the way to V5R1 to take advantage of /Free format logic. Even at V3R1, however, the logic could still have been simplified almost as much, although not quite as readable due to the inability to indent the If/Else logic and the need to extend the expression to a second line.

C        If     Hours <= 40
C        Eval   Pay = Hours * Rate
C        Else
C        Eval   Pay = (40 * Rate)
C               + ((Hours - 40) * (Rate * 1.5))
C        EndIf

RPG/400‘s lack of understanding of dates made it particularly cumbersome to deal with some fairly common business application needs, such as determining how many days elapsed between two dates or adding some number of days/months/years to a date to obtain a new date. Take a look at the following RPG/400 logic that determines the number of days between a “date” (actually a numeric field containing a value representing a date) and the current system date. In other words, how many days old is the invoice with a date value in the numeric field called MMDDYY?

C        DAYSNC    BEGSR
C                  EXSR DATCLC
C                  MOVE ABSDAT    DATE1   50
C                  MOVE UDATE     MMDDYY
C                  EXSR DATCLC
C                  MOVE ABSDAT    DATE2   50
C        DATE2     SUB  DATE1     NODAYS
C                  ENDSR
C        DATCLC    BEGSR
C                  Z-ADDMTH,MM    DAYS    30
C                  ADD  DD        DAYS
C        MM        IFGT 2
C        YY        DIV  4         TEMP    30
C                  MVR            REM     10
C        REM       IFEQ 0
C                  ADD  1         DAYS
C                  ENDIF
C                  ENDIF
C        YY        IFGT 39
C                  SUB  40        YY
C                  ELSE
C                  ADD  60        YY
C                  ENDIF
C        YY        MULT 365       YD      50
C        YY        DIV  4         LYA     30
C                  MVR            TEMP
C        TEMP      IFGT 0
C                  ADD  1         LYA
C                  ENDIF
C        DAYS      ADD  YD        ABSDAT  50
C                  ADD  LYA       ABSDAT
C                  ENDSR

By the way, this code doesn’t include the additional lines of code needed to define an array containing the number of days in each month of the year and the data to fill that array.

Today’s RPG IV’s date data type and built-in functions can do the same calculation in a single statement:

 NumberOfDays = %Diff( %Date(MMDDYY: *MDY0): %Date(): *D ); 

In addition to using expressions and doing away with temporary result fields, the real bang for the buck in this example is RPG IV’s knowledge of dates and their meaning. Notice that we didn’t even need to define any date data type fields or move data around in the program to do this; we’re still using the same numeric field that the old style logic did. That’s thanks to RPG’s built-in functions that can dynamically convert the numeric value to a “real” date, retrieve the current system date and do the difference calculations all in one simple statement.

Some may claim that that we’re overdramatizing the difference by using a date calculation comparison. But date values are a vital part of almost all business applications. So being able to deal with them in such a simplified manner means most of today’s RPG applications can be dramatically simpler than those of days gone by.

Jon Paris is a technical editor with IBM Systems Magazine and co-owner of Partner400.

Susan Gantner is a technical editor with IBM Systems Magazine and co-owner of Partner400.


comments powered by Disqus

Advertisement

Advertisement

2018 Solutions Edition

A Comprehensive Online Buyer's Guide to Solutions, Services and Education.

New and Improved XML-INTO

Namespace support makes the opcode a viable option

Authenticating on the Web

The finer points of OpenRPGUI, Part 1

The Microphone is Open

Add your voice: Should IBM i include open-source RPG tools?

IBM Systems Magazine Subscribe Box Read Now Link Subscribe Now Link iPad App Google Play Store
IBMi News Sign Up Today! Past News Letters
not mf or hp