Guru: End Of Year Feedback
December 2, 2019 Ted Holt
The year has flown by. Before we know it, it will be 2020. The century is flying by, too. We’ve almost consumed a fifth of it. That seems like a good excuse to see what we might glean from some of your feedback. It’s been a while. More to come next week!
Several readers wrote regarding the need to remove hard-coded values from programs. Jim brought up the problem of compile-time tables and arrays.
I find cases where data is hard coded (state names, product categories are a few examples) for tables or arrays in dozens of programs.
I wish I had thought to mention it. Such tables and arrays are easily replaced with database tables.
Hassan gave a strong warning against hard coding.
I have seen high level officials fired after the hard-coding resulted in stoppage of business.
If you’re looking for a new year’s resolution, refusing to hard code data values would be a good one.
In the last edition of 2018, I wrote about the use of dynamic calls vs. ILE binding. I gave two reasons to link to subprocedures in service programs and Jon was kind enough to add a third:
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 Klement’s HTTPAPI, Expat, YAJL and many, many more that enable RPG programs to play in today’s world.
Right, Jon. I should have thought of that.
I also wrote that speed of calls was secondary to creating an environment that would accommodate procedures. Ed was of another opinion and was good enough to share his experience.
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 (i.e. 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 implemented for that scenario. It was only later that the real power of ILE, i.e., modular programming, was realized. In my small corner of the world, it was all about performance.
You may be right, Ed. I think that the important thing is that we create and use libraries of shared routines, even if we use them for different reasons.
There were two good thoughts on “Guru: IBM i Save File Compression Options.”
John wrote: “It is worth considering that a smaller saved object can result in faster recovery times, and a lot less storage for multiple backup copies. Using compression is one answer.”
“Choosing not to save access paths can also dramatically reduce save time, storage of the backup and therefore CPU time, albeit at the expense of a lot of extra time and CPU when restoring. This may be OK for a small test system.”
“When dealing with recovery, time is usually more of a precious resource than CPU, in my experience.”
I appreciate Steven, who added a reminder about two relatively new CL commands.
“For the CL fans at 7.2 and later are CPYTOARCF and CPYFRMARCF for zipping and unzipping files.”
We got several good comments about Chris Ringer’s article “Guru: Preamble Comments.” When you have a minute read them for yourself. I’ll share Barbara’s comments here:
“Even if you use something that requires check-in comments, like git, I think it’s a good idea to also put change-history comments into the code. If you move to some other change management tool in the future, you’d have to remember to recover the change history and then you’d likely have to add it back into the source so the history wasn’t lost.”
Jay writes about RDi’s split personality: “A note about dragging a source tab outside the RDi window to make it a second window. This is counted as part of the current perspective only. If you then switch perspectives, the second window will vanish but the source member will still be open, just invisible and inaccessible until you switch back to the first perspective. (I am on 9.6.0.4.)”
Regarding null values, Trevor writes: “I find the easiest way to deal with nulls is not to deal with them, at least when just reading a table. Obviously you never access a table directly, but always through a view, right? So for all null-capable fields you do a COALESCE to replace a null with a user-friendly value and your program never needs to know the truth.”
Thanks, Trevor. I use COALESCE, too — when it’s appropriate. If you always coalesce nulls into other values, you may as well not allow nulls in the database. That’s not necessarily a bad thing. Some database gurus advocate that very thing.
Concerning RDi shortcuts, Jay adds the following about quick marks:
* Quick marks you create manually with Alt+Q you can only have one of, but using F3 creates multiple quick marks. So if you are in mainline and F3 on an SR, then another SR, then a procedure call, then a variable definition, then if you use Alt+Left_Arrow multiple times you will go back through that entire history.
* Ctrl-Click on a variable/subroutine/subprocedure has the same effect as F3. Personally I find that easier than clicking on the variable name then pressing F3, because where I keep my hand on the keyboard means Ctrl is an easier press than F3.
Markus wrote in with another helpful tip:
One extremely helpful shortcut I use when I got lost in my code is Ctrl-J — return to the last code line you changed.
In response to Guru: Going Dark In RDi, Steve writes: “I went to the Dark Side on the LPEX editor quite a while ago. A lot of my co-workers followed me. I do suggest playing with the colors (background and foreground) to make them more readable. For example, I changed the background on the ‘Compare added line text’ to Green, and made both the ‘Compare … line’ to white text. It is much easier to see.”
I find the adoption of dark mode intriguing. Now I’m just waiting for the industry to decide that green text on a black background is easiest on the eyes. Then we’ll have come full circle!
In response to Guru: Parsing JSON With DATA-INTO And A Twist, John writes “Do it in Python.”
Jon Paris responds: If the web service (or whatever) consuming the JSON is written in RPG why one earth would you want to jump through hoops trying to interface with Python for this? Python makes a lot of sense for many, many tasks but I think lately it has started to be proposed as the solution to everything. This has been happening with SQL for some time – I guess it is JSON’s turn.
Thanks to all who responded, whether on ITJungle.com, as these did, or in direct email to me. I’m always interested to read your wisdom.
Until next week!
RELATED STORIES
Addressing A Legitimate Question
IBM i Save File Compression Options
Guru Classic: Giving RDi a Split Personality
One Way To Deal With Two Null Formats
Ed’s comment “While I agree with much of the reasoning in this article, I have to strongly disagree about the speed of dynamic calls.” is interesting in a number of ways.
When ILE was first introduced, improving the speed of the call was a major motivator. However, knowing that the problem existed caused the Rochester and Toronto folks to pay a lot of attention to improving call speed even before ILE came along. By the time we got to V3 and ILE RPG was released the performance hit of a conventional dynamic call had been significantly reduced.
So while performance was originally one of the motivating factors, in the end it took second place to the benefits of highly modular programs, Service programs, etc.
In regards to the null values comment, you still have to deal with nulls even if the database doesn’t allow them. We do not allow nulls in our database but things such as a left join still exist. Those can create null fields without any given data in the database being null.