You are currently on IBM Systems Media’s archival website. Click here to view our new website.


Three Good Reasons to Stop Writing Subroutines

Save time and reduce errors with subprocedures


We don’t use subroutines in our code these days. We use subprocedures instead. Subprocedures have been around for years—since V3R2, in fact. Yet, when our Subprocedure Basics sessions are on a conference agenda they’re still among the best attended. Based on that, we must assume that many RPGers are still not regularly coding them. This month we'll discuss why we think you should be using subprocedures instead of subroutines. We’ll follow up next month reviewing how to write them—for those of you who haven't started yet or who’ve only cloned them from others’ examples and have never really learned the basics.

Both subroutines and subprocedures let us segregate and structure our logic. The performance of executing a subroutine versus calling a subprocedure is almost the same, although subroutines are marginally faster. So what makes subprocedures better? We have three primary reasons.

Reason 1: Local Data

Unlike subroutines, subprocedures can have data that’s not only defined inside the procedure, but is also private to that procedure (i.e., the locally defined data can’t be referenced outside the boundaries of the subprocedure). Local data is encapsulated along with the routine’s logic. Prior to IBM i 6.1 (aka V6R1), we could only define local data with D specs, so while fields, arrays and data structures could be local, files couldn’t be made local to a subprocedure. That’s not to say that file I/O can't be done in subprocedures prior to 6.1. That's because subprocedures can access the program's global data, including files, as well as their own local data. Not only that, but starting in V5R2, we’re able to use I/O operations with a Data Structure as the result field and this allowed the use of local data in I/O operations. Beginning with 6.1, subprocedures can include F specs as well as D specs, so we can now define local files too.

Many advantages to this local data concept exist. Perhaps the most significant is the data’s isolation to the specific routine makes maintenance easier, faster and less error prone. Say you're making a modification and you must change a field’s definition or clear out its contents. If that field were used in a subroutine, you’d have to check where else in the program that field was used before proceeding to avoid causing problems elsewhere. This takes time and slows down the maintenance process. Of course, in the interest of speed, we often assume this little work field (called TEMP5) is surely not used elsewhere, so it's not a problem if I make it bigger or smaller. If our assumptions are wrong, the program may fail in an area apparently unrelated to the change we just made or—perhaps even worse—just mess up the database!

On the other hand, if that little work field had been defined as local data inside a subprocedure, it couldn’t have been used anywhere else in the program. So we have far less code to review to accurately determine the impact of the change. Also, since the D and F specs related to the local data are physically close to the logic where they’re used, it's much easier to find them.

Furthermore, we probably wouldn't name that little work field TEMP5 anymore; we'd simply call it TEMP because it no longer matters if there are other fields in the program called TEMP—this one is local to this procedure. We're not suggesting it's a good idea to see how many fields of the same name you can define in one program, but it’s nice that you don’t need to search through the program to find a unique name for those little temporary work fields (or if you don't search, potentially reusing a field defined elsewhere by accident).

As a general rule, we restrict our subprocedure logic to accessing only local data, even though technically they can access global data as well. This practice helps ensure the aforementioned benefits. It also gives us the flexibility to decide later to take this routine to its own source member and compile it separately should we decide to share this code with other programs, which leads us to the second reason we use subprocedures.


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.



2019 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