« Great-Great Granny's iPad | Main | The Cost of Standing Still »

January 16, 2013


Robert Clark

eval(T) has my vote. Apart from the mentioned counter wrap, I would occasionally use it for one-shot utility pgms where a DSPF field is smaller than its database counter-part - and yes, I know these have a nasty habit of becoming production pgms. Would also prefer eval(T) in converted RPG III over the various work arounds for numeric fields.

Luis Rodriguez


I was one who suggested (in the discussion you wrote about) that IBM should have created a EVAL(T) op-code extender. Although I do love /FREE I wonder if, had IBM designed a fuller equivalence between /free and non /free code, its implementation and acceptance would have been quicker.

The first time I was able to program in /free (on a V5R3 machine, as we upgraded straight from an old V4R5 720), the first thing I did was to convert every program I had to modify, not matter how small the change, to free format (with WDSc - not RDP in those days). I quickly found that some things stayed in fixed format (eg. MOVE), giving way to a strange code mix.

My favorite “peeve” is SCAN. In order to being able to use it I have to either emulate it, using free code, or encapsulate it between /end-free and /free (which I absolutely refuse to do).

So yes, I believe that IBM should erase any differences between /free and “fixed” code, not giving anyone excuses for staying in the dark ages (even if that means implementing MOVE in /free :-) )

Best Regards,

Luis Rodriguez

Dan Devoe

I feel that an EVAL(T) opcode would be befeficial.

Presently, when checking for a "rollover" condition - rather than saying something such as "if variable = 999" or "if variable = 9999" etc, I use "if variable = *all'9'" - that way, variable length doesn't matter.

Gerardo Agüero

Is not the %REM BIF enough to solve this problem without further complications? In this case I do not see the need for an EVAL(T)op code.

IMHO, RPG provides enough resources to replace old op codes and document (which I consider the most important part) the intention of the programmer.

Jon Paris


"I wonder if, had IBM designed a fuller equivalence between /free and non /free code, its implementation and acceptance would have been quicker."

No - I don't think it would have made any difference. The vast majority of people I have met who refuse to use /Free use things like MOVE as an excuse. The reality is that they don't want to change. There are a few cases where I would still like to see a direct replacement - for example something like CAST (or CONVERT I guess) to replace the type changes possible with MOVE. But for the most part I think it was way past time to drop the more error prone functions of the language like MOVE and move (pun intended) ahead.

P.S. I still remember when an attendee at COMMON, who had insisted for many years that MOVE was not difficult to understand or error prone, came up to me and apologized. He had just spent his first 24 hour period dealing with a bug introduced by a programmer who didn't understand that MOVE's flexibility could also be a trap for the unwary - and even the wary for that matter.

"My favorite “peeve” is SCAN. In order to being able to use it I have to either emulate it, using free code, or encapsulate it ..."

I don't quite understand this as %Scan replaces it. The only real difference is that %Scan will only report a single instance and does not have the array option of the old SCAN op-code. Personally I'd like to see that as an option but given the ability of %Scan to be embedded in an expression it would be ugly stuff to implement.

If I need the old array output option I just code it as a subproc sp the looping is "hidden"

Luis Rodriguez


I do agree that, as a replacement for the differences between the SCAN op-code and the %SCAN() BIFF the solution is, as you wrote, write a subproc (which is, in fact, the route I chose, as I don’t really like to use the /free - /end-free pair). As per MOVEs, I tend to use data structures, so that one is also a non-issue for me.

My only question is: why? Why did not the language include this when the BIFFs were created?

Regarding your CONVERT suggestion, I suppose we can do with %DEC(), %CHAR() and/or %EDITC(). Just the same, I don’t like to give excuses to anyone for not going the /free way (and yes I know that, most of the time they are just that, excuses :-) )



Barbara Morris

Luis, the reason that %SCAN doesn't have a way of returning an array like the SCAN opcode is that RPG supports using built-in functions in array calculations like this:

positions = %scan('ABC' : strings);

This means the same as
for i = 1 to minimum elements;
positions(i) = %scan('ABC':strings(i));

Any of the operands on the right hand side of an assignment can be arrays as long as the left hand side is an array.

Even though most RPG programmers don't take advantage of this, we thought it would be confusing (to the compiler if not to RPG programmers) if a built-in function could sometimes return an array, which would mean that %SCAN would not behave the same as the other built-ins in "multiple element indexing".

The same reason precluded supporting arrays for %SCANRPL, even though it would have been nice to code
newString = %SCANRPL(fromArray : toArray : oldString);

Speaking of %SCANRPL, I'm wondering if %SCANRPL has taken away most of the reasons for wanting %SCAN to return all the instances.


I'd say there is no need for EVAL(T). When converting old fixed-format code into free I would recode pieces which cannot be easily converted like MOVE operations and - yuk - GOTO, CABEQ etc. So the source is really being modernized and gets more structured. Converting legacy code into free-format just to give it a more modern look doesn't make too much sense to me.

> positions = %scan('ABC' : strings);
Thanks Barbara, didn't know this. Great!


The comments to this entry are closed.