RPG Rules!

Article ID: 21050

You can interpret this article's title two different ways. It means either that I really love RPG ("it rules!") or that I want to provide a set of required policies ("rules") that you should use when working with RPG. Which way do I mean it? Both! In this article, I discuss not only why I love the language but also the rules that you should follow if you want your applications to be modern.

RPG is a great language, and I do love it. However, it's not a young language. It's the result of more than 40 years of evolution. In my opinion, RPG is the best language on the planet for writing business rules, but at the same time, it continues to support a lot of archaic features to provide backward compatibility. These archaic features are best described as "legacy features," and you shouldn't get caught using them today.

Why Does RPG Rule?

Despite the legacy, the fact that RPG was designed to be a language for writing business applications specifically for the System i family of computers (and its predecessors) makes it one of the best languages to develop in today. Until you've developed business applications on other platforms using other languages, it's hard to appreciate what we have in RPG. Newer languages sound good, but when you use them, you often find yourself missing some of RPG's elegance. I've compiled a short list of the reasons that RPG rules.

Simplicity. I just want to run my business. I don't want to worry about the technology behind it. I just want it to work so I can concentrate on the business.

Proper decimal support. Businesses operate on decimal arithmetic. Although all programming languages have built-in, well-integrated support for integer and floating point arithmetic, many do not have the same level of support for true decimal types. Integer data doesn't support fractions. Floating point uses approximate values and rounding that can cause errors with decimal data. True decimal types, such as zoned and packed, do exactly what businesses need to do: They let you add up numbers, such as quantities, weights, and monetary values, easily. In RPG, decimal arithmetic is automatic. You don't have to worry about it; it just works. In many other languages, you have to call a special API to get true decimal support, or you have to do without decimal math and work around the flaws in floating point or integer types.

Proper error handling. When an RPG operation fails, you are sent an escape message. Unless you write code to trap that error and handle it, your program crashes. Some other programming languages lack this feature. Their core functions return errors in an error field in the program, and you have to write additional code to check for that error. In those other languages, if you fail to check for and handle the error, the program continues running as if nothing's wrong, only to cause some obscure problem later that's hard to trace to the origin. This default behavior of ignoring errors leads to strange problems that people can't troubleshoot, so the solution is to do things such as reinstall or reboot. How often have you done that with an RPG program?

Deep integration with the database. Business applications tend to use a lot of database logic. RPG was designed from the ground up as a language that uses the operating system's built-in database in the most natural and simple way. When you want to get a record from a database, you code a statement that reads the record, and you're done. Even if you want to code a more complex SQL statement in your RPG program, you code the statement and tell it where to insert or return data into your RPG variable names. It's easy. Some other languages require you to call a complex set of API functions for SQL. Others force you to use ordinal SQL column numbers instead of simple variable names.

Deep integration with the operating system. i5/OS is the best operating system on earth. Its stability, technology independence, virtualization engine, work management features, diagnostics, security, and integrated database make it one of the best tools out there. Although lots of programming languages for i5/OS exist, most of them are available for every other operating system as well. How can you truly take advantage of the power of your operating system if your program can be run anywhere? Cobol and C must conform to ANSI standards. Java, PHP, and Perl all run the same on other platforms as they do on the System i. Only RPG and CL are designed for i5/OS and deeply integrated with i5/OS to the point where you can take complete advantage of its features.

Job logs. This point really is part of the integration with the operating system, but I made it a separate item because it's the feature that I miss the most when I work in certain other languages or when I work on other platforms. I really love the i5/OS job log. I appreciate being able to pull up the WRKACTJOB display, choose the job that's having errors, and display the job log for that job, showing everything that happened. Sure, other platforms have logging facilities, but every program uses a different logging facility in a different way! Granted, many native i5/OS languages use the job log just as RPG does, but some do not — and that's a big deal to me.

Compatibility for the future. Aside from CL, RPG is the only language whose destiny IBM completely controls. RPG has proven over time that you can write a program in it today, and it will still compile and run on the system five or 10 years later. IBM has done a fantastic job of keeping RPG forward compatible. When a company invests its development dollars in RPG, the investment will last for many years to come. Consider the applications that RPG programmers maintain today and ask yourself, if these had been written in another language, would they still be used today? Unfortunately, this forward compatibility can be a double-edged sword. Because the RPG programs continue to run and get the job done without modification, programmers often rest on their laurels, neglecting to replace outdated or legacy techniques. That neglect, in turn, leads to stagnation in the industry. Like I said, it's a double-edged sword.

Rules to Live by When Developing in RPG

When you don't update your applications or improve your technology, you fall behind. Unfortunately, that's happened a lot in the System i industry. Applications work so well that, all too often, programmers continue to write them the same way they did 10 or 15 years ago, which has led to many people thinking that RPG is incapable of providing modern features. Indeed, many people associate RPG and the 5250 green screen, as if the two are a mated pair! The only way to change this perception is by showing people that RPG can do much more than green screen. The best way to show people is to update your programs.

What follows is a list of rules (and I'm sure I missed some) that you should use when you write a new RPG program today.

Encapsulate business and database logic. When you "encapsulate" code, you isolate that code and hide how it works. The basic idea is that a program calling a subprocedure shouldn't know or care how that procedure works. You should be able to completely change the way the procedure works yet keep the parameter list the same, and the caller should continue to function without knowing the difference. For example, if you have a retrieveItemPrice() subprocedure, the routine calling it shouldn't care which physical file is used to store an item's price, or even whether a database is used at all. Perhaps in five years, instead of using a price file, it will calculate the price by adding up the current market values — obtained from the Internet — of the raw materials. When you encapsulate code, you cut down on the cost of maintaining that code, because you can change it without having to change or even test all its callers. Encapsulation makes changing your code easier as your business changes.

Never mix business logic with display logic. Business logic is the logic that controls how your business works. How is data stored? What values are allowed in fields? How do we calculate a price? How do we apply costs to the general ledger? This is very different from how screens are displayed to the user. Keep the user interface separate from the business logic. In the future, you might want to change your display technology. If you're using green screen today, you might want to use web or GUI tomorrow. Or perhaps you'll want your business logic to be accessed by an SQL statement or a web service. Write your code so that it can be refaced without having to be rewritten.

Provide a rich library of services, not monolithic programs. Suppose you want to invent your own programming language designed just for your business. What opcodes would your language provide? Maybe you'd have opcodes named CreateOrder, AddItem, DisplayOrder, InvoiceItems, and MarkPaid? Design your applications as a series of relatively simple routines that do one thing independently of everything else. You should be able to develop whole applications simply by calling these routines. They should be callable from any other programming language so that you can keep reusing these tools, no matter where you go in the future.

Use prototypes, not CALL/CALLB/PARM. I'm always stunned when I see someone still using the old CALL, CALLB, PLIST, and PARM opcodes in RPG. Prototypes can do everything that these old opcodes can do. Plus, over the past 11 years, all the enhancements made with regard to calling programs, procedures, and methods have been made only to prototypes. Don't get stuck using the old method of calling routines, or you'll be trapped in the 20th century forever.

Use string operations, not arrays. Before the release of RPG IV, we could not do proper string manipulation in RPG, so programmers often moved their strings to an array of 1A fields and then used that array to manipulate the string. This practice has been unnecessary since 1995! Come on, folks — it breaks my heart every time I see people still doing this.

Use expressions, not ADD/MULT/SUB/DIV. Today's RPG programs use expressions for all math operations. Modern programs no longer use the legacy ADD, MULT, SUB, and DIV opcodes.

Use procedures, not subroutines. There's no longer a reason to use a subroutine when writing new code. Subroutines restrict you to using global variables rather than local ones or parameters, and that makes code harder to maintain. Modern code uses subprocedures exclusively.

Use named indicators, not numbered. There's nothing wrong with using indicators in your programs. Every language has the concept of a flag or Boolean field, which is what RPG programmers call an indicator. However, all variables in your program, including indicators, should have meaningful names that make identifying the purpose behind the variable simple. If I'm reading your code, and I see a variable named ErrorOccurred, it's pretty clear that it's set to *ON when an error has occurred and *OFF otherwise. However, if I see a variable named *IN74, I have no clue what it means. Sure, I can do research to find out, but that's taking time and making me less productive. Make your programs easy to maintain and easy to follow. Use built-in functions (BIFs) to replace indicators where possible, and when that's not an option, use a named indicator, not a numbered one. There's no reason to use a numbered indicator in today's RPG.

Qualify your data structures. If I see a variable used in your program, it should be obvious, just from the name, whether the variable is part of a data structure. Too often, I've read a program and seen a variable and said to myself, "Where the heck did that get set?" only to learn that a previous line of code was actually changing a data structure. In legacy RPG, it was hard to tell the difference between regular variables and those that were part of a structure. In today's RPG, you should use qualified data structures so it's always obvious.

Use qualified structures for files. Just as data structure subfields should be obvious, so should fields from files. RPG provides the ability to use qualified, externally defined data structures for fields in a file. Personally, I name the data structures after the files themselves. For example, if I have a file named CUSTMAS, I read that file into a data structure named CUSTMAS1. If I need more than one record in memory at once, the second one is called CUSTMAS2, and so forth. Because the data structures are qualified, my code references the fields as CUSTMAS1.Custno, CUSTMAS1.Name, CUSTMAS1.Address, CUSTMAS1.PhoneNo, and so forth. This naming makes it obvious which file each field comes from and makes avoiding name clashes between different files easy. The EVAL-CORR opcode released in V5R4 lets you easily move fields with matching names to the corresponding field in a different data structure.

Take advantage of features in other languages. One of the biggest challenges that RPG shops have is the lack of free tools and add-ins for the language. Suppose you need a routine that can write to an Excel spreadsheet, or a library of routines for generating graphs and charts. Lots of these tools are available for languages such as C and Java, but very few for RPG. Don't let that stop you! Take advantage of RPG's ability to call programs, procedures, and methods written in other languages. In RPG, you can call Java routines or any ILE language routines directly, just by creating the correct prototypes. That way, the world of third-party tools (many of which are free) is available to you without sacrificing the advantages of the RPG language.

Use SQL where appropriate, never OPNQRYF. At times, using RPG's native record I/O functions still makes sense when working with databases, particularly when the file is a transactional file in which you work with one record at a time. However, when the time comes to write routines that use set-based processing, use SQL. With the embedded SQL preprocessor, you can embed SQL statements in your RPG code as easily as RPG opcodes. The power and rich features of SQL make it a natural tool for selecting a set of records that matches particular criteria. Do not use OPNQRYF in modern applications. OPNQRYF is clearly a legacy of the past. SQL is more powerful, easier to use (after you've learned how), and much faster than OPNQRYF.

Use green screens no more! Please stop perpetuating the myth that RPG is only for green-screen programming. Those 5250 terminals are 1970s technology, folks — even MS-DOS programs of the early '80s were far more advanced. It's time to move on. Figure 1 shows an example of what an RPG screen looks like today. Figure 2 similarly shows what a printout looks like. Today's applications are replacing 5250 with web interfaces, not just for public applications but also for internal applications, even when the application is to be used only by employees in the same office as your System i. Web interfaces provide a "thin client" capability in which all the program logic (both business and display logic) resides on the server, greatly simplifying deploying, distributing, and maintaining your application when compared with the "thick client" solutions of yesterday's client/server programs. CGIDEV2 provides an easy way for RPG programmers to use a web interface in a pure RPG environment. If you keep your business logic separate from your display logic, it's also easy to use RPG in conjunction with Java, .NET, or PHP to provide a rich web front end.

The Future Rules

Some prominent folks at IBM have told me that RPG will continue to be developed and enhanced for the foreseeable future. That means more modern features as the years go on. That does not mean that you can keep writing your programs the same way you did in the '80s and '90s! Computer technology keeps evolving, and your programs must evolve as well.

You don't have to evolve everything at once, but start incorporating modern techniques little by little into your programs. As your programs become more modern, easier to maintain, and more flexible, as well as gain nicer interfaces, even your users will be saying that RPG rules.

Scott Klement is the editor of the System iNetwork Programming Tips e-mail newsletter, a System iNEWS technical editor, and a Forum Pro on the System iNetwork . He is also the IT manager at Klement Sausage Co., Inc. You can e-mail Scott at SystemiNEWS@ScottKlement.com.

ProVIP Sponsors

ProVIP Sponsors