One thing that is surely ingrained in RPG programmers' heads is the use of subroutines. Hardly an RPG program exists today without subroutines (although I have recently had the "privilege" of working with one that has no subroutines--it isn't pretty!)
If you have my original RPG book, you've probably read the passage about my RPG instructor in college who, after reviewing my assignment, pointed to my EXSR statement and asked, "What's that?" Obviously, RPG was not his first language.
With virtually all iSeries shops having made the decision to migrate to RPG IV, the issue of subroutines is going to be an important one. Let me state first that there is nothing wrong with subroutines, nor do I think using them makes for bad programming. In fact, I believe just the opposite; subroutines are an important part of any successful RPG II or RPG III application. In addition, they are a viable holding ground for any RPG III application converted to RPG IV.
But in RPG IV, subroutines have strong competition in subprocedures. Subprocedures are so powerful and effective that I would suggest that if the developers at IBM had designed RPG IV without the burden of being 100% compatible with RPG III, they may not have instituted both subroutines and subprocedures--I believe only subprocedures would have made it into RPG IV.
Let's compare these two technologies.
Subroutines have access to what is now referred to as "global variables." Global variables are what we call every field and data structure declared in an RPG III source member, as well as all fields and data structures declared outside of subprocedures in RPG IV.
Subprocedures have access to these global variables in exactly the same way as subroutines.
Subroutines do not provide a way to scope variables to the subroutine; that is, there is no way to declare a field within a subroutine and protect it from being modified outside of that subroutine. This makes declaring work fields an art form.
Subprocedures provide support for what are called "local variables." Local variables are fields and data structures that are declared within a subprocedure. Those fields do not exist to the parts of the program that are outside of the subprocedure. In fact, local variables (by default) are created when the subprocedure is called, and they are destroyed when the subprocedure ends. Because of this local declaration, local variable names do not need to be unique throughout the RPG IV source member. You can declare a field within one subprocedure and declare another field with the same name within a second subprocedure; the two fields are completely separate and have no relationship to one another. Thus work-field naming no longer requires such creativity.
Subroutines do not provide a way to pass parameters to them. When calling a subroutine, you have to move all your fields to a set of work fields, call the subroutine, and then move the data from the work fields back to the original fields. Alternatively, you could, of course, write a subroutine that works with the original field names, but that can be problematic itself.
Subprocedures provide an even greater level of support for parameters than traditional program-to-program calls. Imagine calling a subroutine and passing it the field names and values you want it to manipulate. You can do that easily with subprocedures.
Subroutines are nearly as fast as inline code. A subroutine call is (internally) nothing more than an enhanced GOTO opcode. So entering and returning from a subroutine is about as fast as you can get without writing inline code.
There's no question subroutines will for the foreseeable future be faster to call than subprocedures. Subprocedures have additional overhead when they are called, far above that of a subroutine. The reason subprocedures have more overhead is because they do so much more. There is, in some languages, the capability of asking the compiler to "inline" the code for a subprocedure; sadly, IBM did not include that feature in RPG IV.
Of course, the overhead of the call to the subroutine or subprocedure is only one part of the overhead of a routine. The code in the routine is also a consideration, and in this context, both subroutines and procedures perform identically.
Subroutines can only be evoked with the EXSR and CASxx operation codes. This limits the ability to call the subroutine to a few situations.
Subprocedures may be called with the CALLB or CALLP operation codes, allowing you to pass parameters. In addition, a subprocedure may be called implicitly by coding it in an expression or conditional statement. This means you can evoke a procedure from, for example, an IF statement and get a value returned back to you within the expression. This gives you the ability to extend RPG IV with new functionality. Extending RPG IV with new functions is the foundation behind third-party add-on libraries such as the RPG ToolKit.
Breaking Old Habits
We have to teach ourselves to start asking the question, "Would this code be a good candidate for a subprocedure?" The answer will almost always be "yes."
In fact, I believe you should stop writing subroutines altogether when you move to RPG IV. I've seen some pretty convoluted subprocedures being created by experienced RPG III developers after having just moved to RPG IV. These subprocedures are nothing more than traditional main-line calcs stuffed into a subprocedure. That subprocedure, in turn, calls several subroutines within the subprocedure. That's just wrong.
The best way to stop an old habit, in my view, is cold turkey; just stop doing it. Don't wean yourself off subroutines by mixing subroutines and subprocedures; they are different animals. Subprocedures can do everything subroutines can do and lots, lots more.
In 2003 and beyond, there is no reason to be using subroutines in RPG IV source code. Let's work together to try to put and end to subroutines in new code and migrate toward subprocedures. Believe me, it's for your own good.
Bob Cozzi has been programming in RPG since 1978. Since then, he has written many articles and several books, including The Modern RPG IV Language--the most widely used RPG reference manual in the world. Bob is also a very popular speaker at industry events such as COMMON and RPG World and is the author of his own Web site, www.rpgiv.com, and of the RPG ToolKit, an add-on library for RPG IV programmers. Bob runs his own one-man iSeries consulting and contract programming firm in the Chicago area.