Guru 2020: Suggested Resolutions, One Prediction
January 6, 2020 Ted Holt
Do you eat candy made of underwear? How are your telepathy and teleportation skills? How long ago did you give up eating? How many choppers are on the family helipad? Is your chauffeur a gorilla? Read about these and other bizarre predictions for 2020 here.
A new year is invariably accompanied by resolutions and predictions. I don’t intend to make any of either. However, if you’re into making resolutions, I’ve got some suggestions that you can take or leave, as you wish. As for predictions, I’ve got one that can’t miss.
For RPG programmers who are still looking for a good New Year’s resolution, try this one:
I resolve to quit using global variables.
This is not hard to do and it will make all the difference in the world in your programming. Suppose you work for a factory and have been assigned a project. The users have requested a program that will let them zero out the on-hand quantity (also known as the balance) of any item in inventory.
That sounds easy enough. Here’s part of a display file that they can use to enter an item number.
A R PROMPT A 5 8'Item:' A D_ITEMNO 6 B 5 14
Here’s some RPG source code to zero out the balance.
exfmt prompt; exsr SetBal; begsr SetBal; chain D_ItemNo ItemBalRec; if %found(); Balance = *zero; update ItemBalRec; endif; endsr;
So what’s wrong with this? It works. It gets the job done.
What’s wrong is that this isn’t portable or reusable. Do this instead:
exfmt prompt; SetBalance (D_ItemNo); dcl-proc SetBalance; dcl-pi *n; inItemNumber char(6) const; end-pi; chain inItemNumber ItemBalRec; if %found(); Balance = *zero; update ItemBalRec; endif; end-proc SetBalance;
You have replaced the subroutine with a subprocedure that does not reference the item number from the display file. Instead, the subprocedure requires the item number from the display file to be passed in as a parameter.
The subprocedure still has a global reference however — the item balance file. Here’s an even better version.
exfmt prompt; SetBalance (D_ItemNo); return; dcl-proc SetBalance; dcl-pi *n; inItemNumber char(6) const; end-pi; exec sql update ItemBal set Balance = 0 where ItemNo = :inItemNumber; end-proc SetBalance;
This subprocedure is portable. I could put it into a service program and call it from all sorts of places. And it’s adaptable to change.
Here’s a possible database-related New Year’s resolution:
I resolve to access the database less through tables and more through views.
Let’s say that it is very common when querying the database to access only items that have a positive on-hand balance. As far as business requirements are concerned, an item with a zero or negative balance does not exist. You could use a WHERE clause in your queries to select only those items.
where balance > 0
You would have a lot of queries with that WHERE clause, and you’d have to remember to include that test.
It might be better to create a view that allows you to imagine that every item in the database has a positive quantity on hand.
create view PosItems as select * from ItemBal where balance > 0
You can do a lot of things with views to create your alternate reality. You can:
- rename fields
- redefine fields, even to different data types
- create virtual (non-existent, or calculated) columns
- make data from two or more tables appear as if it were stored in only one table
- and more. . .
What you end up with is this:
The programs access the imaginary view of the database, which hides the real view of the database. This is a huge help when you need to change the database in accordance with changing business requirements, as it sometimes reduces or eliminates the need to change programs when the table structures change.
I won’t delve into this any deeper at the moment. Expect more about this topic from Paul Tuohy soon.
Here’s one last resolution for your consideration:
I resolve to practice YAGNI.
In my younger days, I would sometimes exceed the users’ requests, adding features that I thought would be helpful. As far as I know, most of those additional, unrequested features went unused.
YAGNI stands for “You ain’t gonna need it.” This means that you should not try to anticipate what the business will need in the future, but should provide them only with what they ask for. Programming to anticipate future needs is a widespread practice and rarely effective. Google YAGNI and you’ll find all sorts of reasons why.
I like the way XKCD illustrates it:
Consider the previous two resolutions. The programmer assigned to write a routine to zero out the on-hand balance of an item might think, “Hmmm. They’ll probably need to set the balance to something other than zero eventually. I’ll write a routine that lets them set the balance to any number they choose, including zero.”
Don’t do it! They didn’t ask for it! They may never use it! If you have an idea, present it to the users. If they think it’s a good idea, fine. If not, let it go.
If someday the users decide they want a way to plug in any balance, you can enhance your routine:
dcl-proc SetBalance; dcl-pi *n; inItemNumber char(6) const; inBalance packed(3) const options(*nopass); end-pi; dcl-s NewBalance like(inBalance); if %parms() >= 2; NewBalance = inBalance; else; NewBalance = *zero; endif; exec sql update ItemBal set Balance = :NewBalance where ItemNo = :inItemNumber; end-proc SetBalance;
The else isn’t necessary — NewBalance is initially zero — but it makes the intended behavior obvious. Existing calls to SetBalance work as always. New calls can pass the second parameter if needed.
As for the view example, I have worked on software that only accessed the database through logical files. It works, but it may be overkill. A more realistic approach is to create views only as they’re needed, rather than trying to anticipate the ways the data will need to be presented. In that case, database access looks like this:
My Prediction.
I don’t make New Year’s resolutions because I strive for continuous improvement all year long. Nor do I make predictions. I’m not a psychic, entrails should be buried, and my crystal ball is in the shop for repair.
However, I have one prediction for IT professionals. If instead of trying to predict the future needs of the users, you will design your systems (the database and the software) so that they are flexible, I predict you’ll have greater success adapting to changing business needs.
Happy New Year!
RELATED STORIES
23 Hilarious Predictions About the Year 2020 That Are Way Off
Excellent advice! Your advice is always such a great balance between theoretical “best practice” and pragmatism. The little detail of including the Else when using the *NoPass parm makes such a difference. I’m going to add that to my charts on using *NoPass. Thanks, Ted.
Hi Ted, your reference to YAGNI was new to me. Most of the time, I’d add a little extra to whatever I’m doing to make the coding more flexible because invariably someone would come back later with a request for more. It may be a hard habit to break but you suggested mentioning it to the user which makes sense. My experience with most users was they didn’t know what they wanted until they could see it. But I will strive for YAGNI going forward. Thanks for more great stuff.