Guru: Addressing A Legitimate Question
December 10, 2018 Ted Holt
This is the last Monday issue of The Four Hundred for 2018. My, how time flies! I like to do something different at year end. In previous years I have solved Sudoku puzzles, found my way through mazes, solved the peg game, and more. This year I wish to honor a request that has come from various people and to address what they consider to be a legitimate question.
As I wrote recently, the question I hear occasionally goes something like this: “Why bother with service programs? Why not use dynamic calls?” Rather than insult the person who asks me such a question, which wouldn’t do anything to make the world a better place to live in, I assume that the questioner is sincere and wants a sincere answer. Here goes! I’ll give it my best shot!
It’s Not About Speed
Dynamic calls are fast. As I pointed out in my recent article, IBM used to tell people that one of the nice things about the System/38 was that there was no need for a linkage editor because dynamic calls were fast. On the S/38 and in the early days of the AS/400, dynamic calls were the only type of call supported by RPG, COBOL, and CL. With V2R3 (if I Googled correctly), IBM introduced the Integrated Language Environment, or ILE. That was in 1993. In case you’re not doing the math that was 25 years ago. My, how time flies!
It was as if the good people at IBM changed their minds. I remember some wag posting somewhere in cyberspace that ILE stood for “It’s a Linkage Editor.” Suddenly we had modules and service programs — new object types that held indirectly executable code. You couldn’t call these objects from a command line. You had to call the routines they exported from programs. And as if that weren’t enough complexity, we got binder language, binding directories and activation groups. Oh, for the simple life!
Of course, dynamic calls didn’t go away. To this day we use dynamic calls to run programs. The new procedural calls were intended for libraries of routines — routines that we write once and use many times from many places.
Why did IBM complicate our lives? I can tell you this: it wasn’t about speed. Dynamic calls are fast. It was about making the system a comfortable place for procedure-based languages to reside. I won’t say that subprocedures could not have been implemented in the RPG III compiler under OPM, but the only reason I won’t say it is that I know nothing of the entrails of OS/400 and its successors. The best I can do is to suspect it. And I do! Strongly!
Let’s Be Practical
That’s all well and good, but when it comes down to the programming that runs an organization day by day, does it really matter whether we (a) call programs dynamically or (b) call subprocedures in service programs? I think it matters, for a few reasons that come to mind.
- Dynamic calls to utilities can get messy. Since each call to a utility program requires the same parameter list, but different functions of the utility require different parameter lists, each call can be a group of values shoe-horned into a list of variables. Let me give you an example.
In the days when we still generated a lot of paper, it was not uncommon for me to need to print from CL programs. (I still do occasionally. See here and here.) One technique that I used over and over was to call an RPG program to write to the printer file. Every call had the same format, which typically looked like this:
CHGVAR VAR(&PARM1) VALUE('OPEN') CHGVAR VAR(&PARM2) VALUE('DELETED OBJECTS' *BCAT &TODAY) CALL PRINTPGM (&PARM1 &PARM2 &PARM3 &PARM4)
&PARM1 might be the “action” parameter, and would have different values, such as OPEN, WRITE, EJECT, and CLOSE. Depending on the value of the first parameter, the other three parameters would take on differing roles. All parameters had to be of some large character type in order to accommodate the various types of data.
Or maybe I would have many parameters, and for each type of action I would use or ignore parameters as required.
CALL PRINTPGM (&ACTION &PAGEHEADER &DETAILDTA + &SKIPB &SKIPA &SPACEB &SPACEA)
With a service program, each procedure has exactly the parameter list it needs. Neat! Straightforward!
- A program can’t serve as a function. Like the built-in functions that we depend on heavily, a subprocedure can return a value, which can be stored in a variable or used in a test.
Try that with a program. It won’t work!
- I’ve got two reasons that I think are superb. Do I have to have a third?
It’s About Change
And it’s about time we changed. I suspect that behind these questions is a resistance to change. (I could be wrong. I don’t know what’s going on in other people’s heads.)
ILE is wonderful, and it — along with this wonderful DB2 for i DBMS — will continue to serve us well for years to come, but the ILE model of programming can’t address all the demands of a networked world any more than OPM could address the challenges of the 1990s. Or if it can, ILE can’t address modern demands as well as “modern” languages can. The “modern” languages frustrate me, mainly because it seems a new one arrives every few months accompanied by no shortage of pundits and cheerleaders averring that the new language is the be-all and end-all. Nevertheless, this process of churning through language after language after language is necessary for humanity to eventually find something that will serve our purposes. Maybe then we can all take a breath! (Don’t count on it!)
So lest you and I sit back smugly with a big smirk on our faces because we learned to write subprocedures and service programs a long time ago, let’s keep in mind that if you and I refuse to change, we also will be behind the times, the epitome of superannuation. (How out-of-date we are is irrelevant, so we’ll be no better than the guy who’s still writing RPG II programs to run in the S/36 environment.)
This year I participated in my first Node.js project. I was as uncomfortable as if I had put my underwear on backward. I still have not mastered Git. But I got through the project and I learned a lot, and in 2019 I will tackle more Node.js projects with confidence and enthusiasm.
A Note Of Thanks
I am not smart enough to do anything alone. Over the past 37 years, many people have helped me attain some modicum of success as an information technology professional. I want to end the year by thanking the many people from whom I have learned this year. (Some of you know may who you are, but most of you don’t even suspect that you helped me.)
Since I can’t name everyone, I have selected one person to use as an example. In my article Refactoring into Routines, astute reader Rocky — I know he’s astute; I have met him and I have read his online posts — suggested that I put the name of a subprocedure not only in the procedure declaration (DCL-PROC) and prototype declaration (DCL-PR), but also in END-PROC, DCL-PI, END-PI, and END-PR. He felt that doing so made the code more self-documenting, and I decided that I agree. I have changed my practice. Thanks, Rocky! You made a difference!
Thanks to everyone who reads this newsletter. Thanks especially to those of you who give me feedback, either by posting comments on the web site or by email. Please keep the feedback rolling in so I can try to give you helpful information.
Merry Christmas! May 2019 be our best year ever!
RELATED STORIES
Stuff I Didn’t Publish This Year (2006)
Stuff I Didn’t Publish This Year (2007)
The Binding Directory Is The Key
Integrated Language Environment Description
While I agree with much of the reasoning in this article, I have to strongly disagree about the speed of dynamic calls. While maybe not the primary factor, speed was certainly a contributing factor. I helped several S/38 and early AS/400 customers rewrite applications to put common code inline and avoid dynamic calls precisely to avoid iterative (ie thousands of) dynamic calls. Using EXSR instead of CALL took about 1/100th the time. When ILE finally came to RPG, we found that CALLB / CALLP was nearly as fast as EXSR, so ILE methods were quickly for that scenario. It was only later that the real power of ILE, ie modular programming was realized. In my small corner of the world, It was all about performance.
IMHO.
Ted, when you write “Rather than insult the person who asks me such a question, . . . ” you just insulted anyone who has ever asked you that question.
But I’m sure that wasn’t your intent
Well I can add a third reason to your list Ted. Dynamic calls provide no option for passing parameters by value. This is the mechanism that C in particular uses and without being able to call C functions we would not have been able to handle IFS files in RPG programs. Or use utilities like Scott’s HTTPAPI, Expat, JAJL and many, many more that enable RPG programs to play in today’s world.