I'm getting so tired of a vocal minority giving IBM advice on new RPG IV features while the vast hundreds of thousands sit quietly by and say virtually nothing. Not every piece of advice is for an ostentatious feature, but some ideas are. I admit that my own list is no less pretentious than the list any other cage-rattler would create, but hey, I "wrote the book."
But seriously, do you really want to sit quietly by as features are introduced that will impact the language in perpetuity?
For example, EVAL-CORR is a proposed enhancement that would copy data structures to other data structures. MOVE CORRESPONDING is the COBOL equivalent and the origin of this requirement. It copies each subfield of one data structure to the same field name in a second data structure. That's long overdue in RPG IV, and it will benefit us with QUALIFIED data structures.
The problem with EVAL-CORR is the embedded hyphen in the opcode name. Do we really want all new opcodes to contain an embedded hyphen? The Z-ADD opcode is being used as the precedent for moving in this direction. Of course Z-ADD isn't supported in /free RPG IV, so using Z-ADD to justify it isn't valid in my mind.
Hyphens should never be used within an operation code, nor should any other operation code separator be used. The opcode should be named EVALC, EVALCORR, ECORR, CPYCOR, or something similar. In other words EVAL-CORR will no doubt lead to EVAL-CENTER. Wouldn't you rather use EVALC than EVAL-CENTER and EVALCOR (or something similar) than EVAL-CORR?
The justification for doing the embedded hyphen is... Well, who cares what it is? It isn't right.
1. Move Corresponding Opcode
Continuing our tradition of taking cool features from other languages, the COBOL MOVE CORRESPONDING statement needs to be imported to RPG IV. This feature allows you to copy one qualified data structure to another; copying only the subfields whose names match in both data structures. The subfields are copied based on the names. For example:
D CustNo 7P 0
D CustName 35A
D Address 30A
D City 30A
D BalDue 5P 2
D CustStats DS Qualified
D CtrlID 5I 0
D CustNo 7P 0
D BalDue 5P 2
C EvalMap CustStats = Customer
In the example above, specific subfields of the data structure CUSTOMER are copied to the corresponding subfields in the CUSTSTATS data structure. The opcode name I suggest, EVALMAP (pronounced "Eval with Map" or simply "Eval Map"), is more RPG-like than COBOL's MOVE CORRESPONDING and much, much easier to teach than EVAL-CORR.
2. %RANGE and %VALUES Built-In Functions
If you go back to the days of System/34 SSP, you may remember a little-used language named WSU (pronounced "Woo Soo"). This language had some very cool opcodes, including VALUES and RANGE. Here we are decades later, and RPG IV does not yet have this capability built in.
I think we need both %RANGE and %VALUES as well as %MIN, %MAX, %AVG, and %STDDEV. These built-in functions will do more for the language and programming community than most other enhancements. Why? Because they will be used effectively in nearly all RPG IV programs/modules being written.
For example, with these built-in functions, you could code like this:
C eval Group = 1
C elseif AmtDue = %Range(101 : 1000)
C eval Group = 2
C elseif AmtDue = %Range(1001 : 10000)
C eval Group = 3
C endif
C if Group = %Value(2:3)
C exsr Midrange
C endif
3. %ISxxxx Built-in Functions
I don't know how many times I've needed these features in CGI programming. The ability to test a field for all numeric data, all non-numeric (i.e., alpha) text, or a mix of both without special characters is becoming more and more important every day. It's about time RPG IV goes the following:
- %IsDigits--Does the field contain all numeric digits only?
- %IsAlpha--Does the field contain alpha characters A-Z (in uppercase or lowercase) only?
- %IsAlphaNum--Does the field contain A to Z, a to z, and 0 to 9 only (i.e., no special characters)?
- %IsNum--Does the field contain a valid number, with or without standard numeric editing symbols (decimal, thousands notation, sign, currency symbol)?
All of these built-ins return *ON if they succeed and *OFF if they fail.
4. Initialization of Arrays
When RPG IV came out, IBM ported the decade's only compile-time array and compile-time data. Today, the only reason you use compile-time data is because there's no easy way to initialize an array's elements on the Definition specification. IBM needs to add the following capability to the language:
D Inz('NORTH' : 'SOUTH' :
D 'EAST' : 'WEST')
D RegionCode S 5I 0 Dim(4) Inz(1:2:3:4)
Could it get any easier than this?
5. Typeless Parameters on Subprocedures
Just like built-in functions, the subprocedures we write should also have the capability to allow the caller to specify character, numeric, or date values (any type) for the same parameter. Today, if you declare a parameter as numeric, you can't pass character, and vice versa. Whether this capability is implemented via so-called procedure overloading or through an OPTION(*ANYTYPE) keyword on the parameter definition does not matter. What does matter is having the capability in the language.
6. Default Values for Unspecified Procedure Parameters
When you define a procedure, you have a choice of allowing the caller to specify some value or not. When no value is specified, however, it would be beneficial to be able to specify a default value for that parameter. This way, the value you receive in the subprocedure is defined on the prototype instead of in the procedure logic/code.
7. Improved Performance with Large Return Values
If you've ever written a procedure and had a character return variable or an array as the return value, you know what I'm talking about. RPG IV performance stinks when the length of the return value exceeds a certain (unknown at press time) length.
For example:
D GetCustNames PI 50A Dim(300)
D m_Parm01 7P 0
D m_Parm02 7P 0
D m_Parm03 7P 0
D l_rtnvalue S 50A Dim(300)
** procedure code goes here
** Return value is VERY LARGE
C return l_RtnValue
P GetCustNames E
This procedure returns an array of 300 elements, each of which is 50 bytes in length. Therefore, the procedure returns 15,000 bytes, which can seemingly take centuries to accomplish. This really needs to be enhanced.
8. Multiple Statements per Line on Conditional Logic (/free)
OK, it's not a secret that I'm no fan of the /free syntax in RPG IV. It isn't that I dislike free-format, I just dislike syntax that I have to fight with every time I use it.
One thing that would help is if IBM altered the grammar of the /free syntax to allow multiple statements on a line when conditional statements are used. For example:
if (A = B) ;
code = 3 ;
elseif (C = D) ;
code = 4;
endif;
/end-free
I would much rather have the syntax accept the following:
if (A = B)
code = 3 ;
elseif (C = D)
code = 4;
endif;
/end-free
Even better would be the following:
if (A = B) code = 3;
elseif (C = D) code = 4;
endif;
/end-free
9. Compile-Time and Runtime Support for Add-on Libraries
I suppose this is more problematic than the other requirements on this wish list. What is missing from the iSeries is the ability for vendors to ship both development and runtime software to customers. For example, take the RPG xTools (my own product): Today, I can ship a development version that includes the runtime, but I can't ship just runtime. Why? Because no function exists that allows me to sell a developer version and then give away or greatly reduce the runtime version for systems on which no development is being done.
That is, I can't allow programs to call procedures in this service program, but not allow compiling and linking to the service program; this would allow runtime support. I have no way to restrict one from the other. On other platforms, you do have this capability; if customers license only the runtime version, they can't compile a program that calls the procedures in the service program, but they can buy or install already-compiled programs that use the service program. Those programs have been compiled on a system where the developer version was licensed.
10. Inline Optimization for Procedures
RPG IV's performance is good, but not great. I think IBM tends to believe that you should just buy more CPU cycles to fix your problems. But a compiler should have various levels of optimization to make our own code run faster.
Inline code is a method by which short user-written subprocedures are copied inline by the compile rather than stored in a separate routine. This allows the code to be run slightly faster than if it were inside a procedure.
Today, most but not all of the OS/400 CEExxx APIs are inline routines. If an API begins with the letters "CEE," it is more than likely that the compiled object code is "/copied" into the program, replacing the CALLB or CALLP to the procedure with the actual executable code itself.
RPG IV needs an INLINE keyword on procedures to encourage the compiler, when possible, to "/copy" object code from a procedure as inline code. This does create bigger programs, but they tend to run slightly faster. To the programmer, you don't code anything differently when calling the procedure so the benefit is at runtime.
What Features Do You Want?
I've coordinated this week's survey with this article. So vote for your favorite feature listed above, and we'll let IBM know which ones are most favored by our readers. And if you don't see a feature you'd like, mention it in the forums discussion associated with this article. This is a chance for those of you who don't usually voice your opinion to either vote or make yourself heard!
Bob Cozzi is a programmer/consultant, writer/author, and software developer. His popular RPG xTools add-on subprocedure library for RPG IV is fast becoming a standard with RPG developers. His book The Modern RPG Language has been the most widely used RPG programming book for more than a decade. He, along with others, speaks at and produces the highly popular RPG World conference for RPG programmers.
LATEST COMMENTS
MC Press Online