Since the introduction of the latest Service Pack for IBM i V7 — cunningly entitled ‘Technology Release 7.1 — RPG programmers can now finally eschew the old fixed column coding and roam around a modern free format language. RPG is free. Finally. Lovely jubbly.
Long overdue and in the words of Jon Paris (RPG Guru and all round Nice Geezer):
1) I hate F-specs.
I can never remember which letter goes in which column, and of course the more I use embedded SQL, the less frequently I have to code them. I almost always end up either cloning or using the prompter in RDI (about the only time I ever use it) and even then I’ll get at least one thing wrong.
I also find it frustrating to have to specify every little detail. For example, if I say it is a printer file, then of course the thing is output. How many input-capable printers have you ever encountered?
Forget that the new F-specs are free-format. For me the most liberating thing about them is that they assume sensible defaults! For example, suppose I code this:
Dcl-F MyPrinter Printer;That is all RPG needs. There is no need to specify the “E” for externally described, since that is the default for all files. Similarly there is now a sensible default usage for each file type, and that takes care of having to tell the compiler that my printer is an output file. Isn’t that a pleasant change? Even I can remember how to code that!
How about disk files? Well those are the simplest of all. Want an input disk file? No problem:
Dcl-F ProdData;That’s all I need to code, as the default device type is disk, and it has a default usage of input. I love it! But what if it were a keyed file, and records were to be both added and updated? Equally simple and, perhaps more importantly, a lot more obvious than a “U” and an “A” in some obscure column. Here’s what it would look like:
Dcl-F ProdData Usage(*Update: *Output);2) Requiring that all F-specs come before any D-specs is annoying.
This is particularly true in programs with large numbers of files. I use a lot of data structure I/O and it is annoying to have to separate the two sets of definitions. Same thing applies to control variables used with a specific file. Ideally I’d like to define the file and then follow with all the associated DS, field, and constant definitions.
Well with the new support I can do just that.
// Definition and variables for Product file Dcl-F Product; Dcl-DS ProductRec LikeRec(ProductR); Dcl-C obsoleteProduct 'O'; Dcl-S prodRecCount Int(5); // Definition and variables for report file Dcl-F ProdRptF Printer OflInd(fullPage); Dcl-S fullPage Ind Inz(*On); If fullPage; PrintHeaders(); EndIf;Admittedly an overly simplistic example, but hopefully it gives you the idea.
3) Flipping in and out of free-form for subprocedures is ugly.
This has bugged me ever since the V5R1 introduction of /Free. There I am happily coding away in my little /Free world and I have to switch back to fixed form to start a subprocedure, and then back to free to code the logic before going back to fixed to end the subprocedure. It just makes the code look plain ugly. (Note I also hate those big ugly blobs of asterisks that some people use for comment blocks.) Admittedly part of this problem is alleviated by the simple removal of the requirement to use /Free and /End-Free, which is also part of the new support.
Here’s a really simple example of what I mean. Here’s the pre-liberation version of a super simple subprocedure:
/End-Free P PrintHeaders B /Free Write Heading; pageFull = *Off; Return; /End-Free P E /FreeAs I noted, I can now remove the /Free and /End-Free directives, which gives me this:
P PrintHeaders B Write Heading; pageFull = *Off; Return; P ELess typing, but it still looks a little funky. This is the new version:
Dcl-Proc PrintHeaders; Write Heading; pageFull = *Off; Return; End-Proc;Now I can code a subprocedure, complete with local variables, every bit as easily as a subroutine. That’s one less excuse for the “subroutines were good enough for my grandfather” brigade.
4) I want my legacy to live on.
As I said earlier, I have been working in the midrange arena for more than 45 years. Many of the applications that I wrote way back when are still in use today. I would love to be able to go back and retrofit them with these latest RPG enhancements. Why? Because I take pride in my work and don’t want programmers who work with them in the future to discount them simply because they look ugly (fixed form) and therefore do not match their expectation of what a program should look like.
Over the last few years, my partner Susan and I have trained a lot of Java, C++, C#, PHP and other programmers in the joys of RPG and the IBM i. We always start with modern editors (RDi) and free-form RPG. Always. We have seen so many potential RPG lovers turned off by being introduced first to the old fixed-format version of the language. Even worse to RPG/400, not even RPG IV.
It might surprise you to know that the vast majority of those who we have trained love RPG and the simplicity with which it handles situations that would require much more coding in other languages. As long as they were writing logic (i.e., the free-form calcs), our students had no problems. What drove them crazy was when something as simple as changing a variable name resulted in a multitude of errors because they had inadvertently disrupted the column sensitive portion of the definition. The resulting errors made no sense–after all the line looked pretty much the same as it did before.
The same thing happens with subprocedure definitions. And we’re talking about people who have been trained to build all of their applications around subprocedures. I have seen situations where these folk started off really buzzed by what RPG offers only to become frustrated and disappointed as they progress into subprocedures.
No more. Now we can introduce them to a version of RPG that removes these barriers. And that can only be a good thing.
Read more of Jon’s thoughts on the world of IBM i here