Category:RPG

From MidrangeWiki
(Redirected from RPG)
Jump to: navigation, search

RPG is an acronym which stands for Report Program Generator. It is a programming language developed by IBM originally created for developing business applications.

See also on Wikipedia: RPG programming language

Programmers, coming to RPG from other programming environments, will still need to get some education to familiarize themselves with its capabilities, and how it functions.

There are four major versions of RPG currently in use... RPG II, RPG III, RPG 400, and RPG IV (sometimes referred to as ILE RPG). The latter has two distinctive flavors: the traditional column restricted language entry and the modern /Free alternative where most of the coding can be entered in a non-column restricted way.

RPG is almost exclusively limited to IBM midrange platforms. Various RPG implementations have been developed for other platforms over the years including the IBM 1401, System/360, S/370 and follow-ons; the Hewlett Packard HP3000 [1]; as well as Wang, Sperry, Burroughs, and Digital PDP and VAX computers. These can all be considered niche projects with very little adoption, especially the ones outside IBM.

OS/400 contains extensive support for debugging and run-time identification of RPG code. There is a large established base of RPG code in production environments, usually performing heavy-lifting batch-oriented data tasks, or providing support for interactive ERP applications, either with native 5250 interface or with a graphical user interface (GUI) or Web Skin applied over the 5250 data stream.

RPG vs. other languages

Compared to other programming languages, RPG is especially strong in

  • transactional processing;
  • access to the integrated Db2 database on the IBM i platform;

The main criticisms of RPG center around the language not having enough "modern" features, such as support for object-oriented programming (OOP). However, the language continues to evolve and improve, and already compares favorably with most languages in terms of procedural programming support.

Another area of criticism is lack of direct support for GUI programming, though there are RPG Third Party offerings to fill that gap.

RPG vs. Java

Arguably the biggest difference between these two languages, as used for "business" programming, is that Java is explicitly object-oriented while RPG is not. Java also has a very large ecosystem of third-party packages, most of which are free and open-source, while RPG (as yet) has a very small ecosystem by comparison.

Both coexist and interoperate well on the IBM midrange platform, allowing businesses to leverage the respective strengths of each language on the same machine.

Objects and RPG

This seems to be a persistent bone of contention among those who try to portray RPG as object-oriented, apparently due to some perceived need to "keep up with the Joneses". However, RPG is not object-oriented in any way which would be recognizable to programmers of languages with explicit support for OOP, such as Java, C++, C#, Python, Ruby, Smalltalk, etc.

RPG is about as object-oriented as C or Pascal, which is to say you could use pointers and data structures to create your own notion of "objects". However, this is far more cumbersome and less robust than using the explicit, built-in object-oriented mechanisms (such as classes and inheritance) in the languages recognized by the rest of the computing world as "object-oriented".

What the "RPG-is-object-oriented" proponents invariably describe as object-oriented features are better understood to the rest of the world as modular programming features. In particular, the ILE environment and ILE-related language improvements bring GCC-style modularity and language interoperability to the IBM midrange.

APIs

API stands for Application Program Interface. RPG has access to C functions via service programs in binding directory QC2LE, as well as CEE APIs. There are also APIs specific to IBM i, like IFS access.

A new API mechanism is called IBM Rational Open Access: RPG Edition [1] Open Access is a separately purchased product for IBM i 6.1 and above via handlers similar to using SPECIAL files.

Conditional compilation

Conditional compilation is a mechanism that allows you to include or omit sections of code based on the compilation environment. This is in contrast to editing the code to add or remove sections. A typical reason for conditional compilation is code only used during testing. Imagine a scenario where you're writing a program that will perform a web service. Putting it in debug might be problematic because halting on a breakpoint will stop all web users from seeing results. So you insert code that logs useful information to an IFS file. Unfortunately, leaving that code in all the time slows execution down too much. One solution is conditional compilation.

Conditional compilation uses condition-names as the main driver. In conjunction with condition-names, compiler directives /IF, /ENDIF, /ELSE and /ELSEIF are used to perform the tests the compiler will use to determine whether to include a section of code or not. Condition-names can be predefined by the compiler, or defined by the developer via /DEFINE and /UNDEFINE. There is one last directive, /EOF, which tells the compiler to ignore any remaining source lines in the source member.

An example might make this easier.

      /if defined(LOG_FULL)
        logDebug('customer credit code': creditCode)
        logDebug('customer A/R balance': %editc(balance: 'J')
      /endif

If LOG_FULL is defined, either in the compile command: DEFINE(LOG_FULL), or within the source code: /DEFINE LOG_FULL then this logging code is included and compiled. If LOG_FULL is not defined, that code is not compiled.

RPG comes with some useful predefined condition-names:

i5/OS version Condition-name Purpose
V5R4 *CRTRPGMOD Set if the compilation command is CRTRPGMOD
V5R4 *CRTBNDRPG Set if the compilation command is CRTBNDRPG
V5R4 *VxRxMx Set if the TGTRLS on the compile command is this level OR LATER. For example, if *V5R4M0 is specified, it will evaluate true if TGTRLS is V5R4, 6.1, 7.1 or higher.

Examples:

      /if defined(*CRTBNDRPG)
     H dftactgrp(*no) actgrp('MYCOMPANY')
      /endif
      /if defined(*V5R4M0)
       callp someV5R4API();
      /else
       callp ourHandWrittenVersion();
      /endif


Enhancements

Fall 2019 enhancements for RPG - DATA-GEN, OVERLOAD, OPTIONS(EXACT)

The ILE RPG compiler has several enhancements for 7.3 and 7.4

   The DATA-GEN operation code
   The OVERLOAD keyword for prototypes
   OPTIONS(*EXACT) for prototyped parameters

See details below about the enhancements. PTFs 7.3:

   ILE RPG runtime: SI71535
   ILE RPG compiler: SI71534
   Source files in library QOAR for DATA-GEN: SI71517

7.4:

   ILE RPG runtime: SI71537
   ILE RPG compiler: SI71536
   ILE RPG compiler, TGTRLS(V7R3M0): SI71538
   Source files in library QOAR for DATA-GEN:  SI71518

The PTFs for the compiler and runtime are also available with the Db2 for i Fixpacks of 15 November, 2019. See https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/IBM i Technology Updates/page/Db2 for IBM i 2019 Group PTF Schedule. However, the PTFs that provide the updates for library QOAR are not part of the Db2 for i fixpacks, since they have special instructions regarding saving any changed source in any of the files. Enhancement details New operation code DATA-GEN

DATA-GEN generates a structured document, such as JSON or CSV, from an RPG variable. It requires a generator to generate the document. The DATA-GEN operation calls the generator, passing it the names and values of the RPG variables, and the generator passes the text for the structured document back to the DATA-GEN operation, which places the information into the output file or the output RPG variable.

   DCL-DS product QUALIFIED;
      name VARCHAR(25);
      id CHAR(10);
      price PACKED(9 : 2);
   END-DS product;
   DATA-GEN product %DATA('ProductInfo.JSON' : 'doc=file')
                     %GEN('MYLIB/MYJSONGEN');

Overloaded prototypes

The OVERLOAD keyword defines a list of other prototypes that can be called using the name of the prototype with the OVERLOAD keyword. When the prototype with the OVERLOAD keyword is used in a call operation, the compiler uses the parameters specified for the call to determine which of the candidate prototypes listed in the OVERLOAD keyword to call.


In the following example, FORMAT is defined with the OVERLOAD keyword. For the first call to FORMAT, the parameter has type Date, so FORMAT_DATE is called. For the second call to FORMAT, the parameter has type Time, so FORMAT_TIME is called. For the third call to FORMAT, the parameters have type Character, so FORMAT_MESSAGE is called.

   DCL-PR format_date VARCHAR(100);
      dateParm DATE(*ISO) CONST;
   END-PR;
   DCL-PR format_time VARCHAR(100);
      timeParm TIME(*ISO) CONST;
   END-PR;
   DCL-PR format_message VARCHAR(100);
      msgid CHAR(7) CONST;
      replacement_text VARCHAR(100) CONST OPTIONS(*NOPASS);
   END-PR;
   DCL-PR format VARCHAR(100) OVERLOAD(format_time : format_date : format_message);
   DCL-S result varchar(50);
   result = format(%date());              // 1
   result = format(%time());              // 2
   result = format('MSG0100' : filename); // 3

OPTIONS(*EXACT) for prototyped parameters

When OPTIONS(*EXACT) is specified for a prototyped parameter, additional rules apply to ensure that the called procedure receives the same value as the passed parameter. For example, without OPTIONS(*EXACT), the compiler allows the passed parameter to be longer than the prototyped parameter, and it allows a data structure to be passed that is related by LIKEDS to a different data structure from the passed parameter. With OPTIONS(*EXACT), the passed parameter cannot be longer than the prototyped parameter, and if the prototyped parameter is defined with LIKEDS keyword, the passed parameter must be related by LIKEDS to the same data structure.


In the following example, field fld10 can be passed to parameter parm5 of prototype p1, but the called procedure receives the value "abcde" instead of the full value 'abcdefghij' of fld10. Field fld10 cannot be passed to parameter parm5Exact of prototype p2 because the length, 10, of fld10 is greater than the length, 5, of the prototyped parameter parm5Exact.

   dcl-pr p1;
      parm5 char(5);
   end-pr;
   dcl-pr p2;
      parm5Exact char(5) OPTIONS(*EXACT);
   end-pr;
   dcl-s fld10 char(10) inz('abcdefghij');
   p1 (fld10);
   p2 (fld10);  // Error


This article is a stub. You can help by editing it.


Learning about RPG

Open Source Sites

External Links

  • RPG Developer Network http://www.rpgiv.com/
  • RPGPGM.COM — An extensive resource of articles giving examples of RPG code and related programming https://www.rpgpgm.com
  • "RPG: A Great Language with a Greater History" by Brian Kelly, The Four Hundred, Volume 18, Number 30 -- August 17, 2009 [2]

References

  1. IBM United States Software Announcement 210-114 , IBM Rational Open Access: RPG Edition delivers RPG IV extensibility to access new devices and resources ,13 Apr 2010. Retrieved on 19 Apr 2010