|
Author:
Viking
|
|
2009-06-17 12.16.07 |
Maybe this?
http://www-01.ibm.com/software/support/probsub.html |
|
Author:
CurtisB
|
|
2009-06-17 12.02.39 |
I can understand why there was a certain level of humor in my question; how
likely is it that my request will be heard by the appropriate people, let alone
implemented? I have the feeling SBMJOB might work as well as any other way. ;)
But I was trying to be serious; how would I go about submitting a feature request? |
|
Author:
TFisher
|
|
2009-06-12 13.16.23 |
SBMJOB ;) |
|
Author:
CurtisB
|
|
2009-06-12 13.10.41 |
How do you submit a feature request to IBM? |
|
Author:
HansBoldt
|
|
2009-06-10 14.00.28 |
Bob: It's been about 2 years since I've seen the inside of a compiler. I am an
application programmer now. I also fully understand the necessity for strong
typing in a programming language, whether it's compile-time (as in Java) or
run-time (as in Python), as I'm sure you do too.
But hey, if you think this is important enough, you can always submit a feature
request to IBM. |
|
Author:
Bob Cozzi
|
|
2009-06-10 13.15.35 |
Fish,
Great example. Nested functions was how IBM wanted to do EVALR originally. I really lobbied hard with
George Far to use EVALR instead. Don't know why they never thought of it--probably a forest & trees
thing. But I'm glad it came out the way it is today. |
|
Author:
Bob Cozzi
|
|
2009-06-10 13.11.06 |
Hans,
Aside from emotional issues, the best logical reason I can think of for NOT wanting to wrap nums in
%editc/%char and back again is due to the complexity and length of the expression.
We are NOT writing compilers or graphing tools here on "i"; you might do that on other
platforms where complexity in expressions is standard operating procedure. But RPGIV programmers
at large are generally not as sophisticated as say those who write stuff for/at Microsoft, Oracle, IBM
Canada, Apple, etc. We're writing File Maintenance apps and reports, and typically not writing parsing
routines.
So simplicity and consistency is what works for us.
I'm also a firm believer that if something is needed to be coded by a million programmers, then it
shouldn't need to be coded by any of them--the language should just do it.
A great example is iconv(). Exactly why it hasn't been integrated into the language is beyond my
reasoning. Why I can't declare a field with CCSID(37) and another with CCSID(819) and simply move one to
the other and have the conversion done under the covers is beyond me. |
|
Author:
TFisher
|
|
2009-06-10 12.40.58 |
I don't see the big deal in providing the functionality for numeric data
types. Why does IBM discriminate between data types with functionality like %
SUBST, %SCAN, and %LEN (maybe others)?
Sure, we all know that we can use %EDITC inside of %SUBST. But most of the
time (when we do it anyway) we need the value in a numeric field, not a
character field. That is, VAR = %SUBST(%EDITC(UPSBOOK#:'X'):1:1) will put the
first digit into 'VAR' and 'VAR' must be a character field. So now the
developer must either move VAR into a numeric field, use a DS, or worse they
must build onto the statement more embedded functions.
VAR needs to be a numeric field and we need to be able to do VAR = %SUBNUM
(UPSBOOK:1:1).
|
|
Author:
neilrh
|
|
2009-06-10 11.51.06 |
The annoying thing is when you're calculating a check digit validity, you need
to convert to %char to %subst, then back to %dec to perform the math at the
digit level.
I think the most common implementation I've seen is to put the value in a
signed numeric with array overlay (1s0 array size). |
|
Author:
HansBoldt
|
|
2009-06-10 11.37.38 |
I still don't see the big deal in wrapping the numeric variable with %CHAR or
%EDITC if you want to deal with a numeric in character form.
|
|
Author:
Bob Cozzi
|
|
2009-06-10 10.02.37 |
Hans,
Just to be clear, I was advocating making Zoned compatible with %SUBST and perhaps concatenation
routines but was not advocating support for non-numeric data. |
|
Author:
HansBoldt
|
|
2009-06-10 09.59.05 |
Making zoned decimal numeric compatible with character is an interesting idea.
But implementation would take more than 15 minutes. One problem is that zoned
numeric would have to be added as an exception for all character operations in
the semantic checking. And in code gen, things aren't simple either since W-Code
is strongly typed. You can't mix numeric and character types in W-Code. Doable
certainly, but it's not as straight-forward as you suggest.
|
|
Author:
Bob Cozzi
|
|
2009-06-09 17.21.08 |
This is a good thread. But it seems to have fallen onto the "MOVE/MOVEL in free
format" argument... That horse is dead.
But the points about numerics in non-numeric fields vs numeric fields in
interesting.
I have an ID number for contacts. To make a new ID, I simply add 1 to the
existing number. I also use it for collating (ordering). But those are the only
two things I use it for.
Storing them in character fields would make doing those two things more work
(right justifying them and all).
Perhaps the same thing is true of SSN and credit card numbers. Credit cards have
a self-check number in them (similar to EAN/ISBN numbers) so you do need them in
numerics.
Perhaps what IBM should do with RPG IV, is make Zoned Numeric ("S" data type) a
polymorphic data type--allow it to be used as numeric and character. All it to
work with:
ccn = ccn + 1;
and
ChkDigit = %subst(ccn: 4: 1);
But don't support this capability for Packed/Integer/Float.
I would guess, this would be a 15 minute implementation (plus testing and
evaluation time) why? Becase "S" data-types are effectively character data that
is mapped to Packed "under the covers" anyway.
|
|
Author:
Viking
|
|
2009-06-09 12.14.26 |
I'm convinced that we should have it. While I see the points Hans is making,
and they make sense to me in theory, I can't get away from the fact that in
the real world, we frequently need to do what TFisher is asking for. His
arguments for this BIF are good, but really it's my own experience in needing
to do those exact same things that has me convinced. Nobody's saying we
aren't able to make do without it, but it would be helpful and given the other
BIFs we have, it wouldn't be going against any precedent that hasn't already
been gone against.
Just my $.02. |
|
Author:
TFisher
|
|
2009-06-09 11.42.09 |
I agree with that statement, but I still say we have a case for %SUBNM. I
have seen driver permit "numbers" and driver license "numbers" stored in
database files in the past and these fields were character fields even though
the "description" of the value contained the word "number". It's not the
description of the value, however, that determines the field type. It's the
requirement for the value. These values require the support of alphanumeric
characters (like international zip codes) so the field type is determined
based on that requirement and not what we call the data element.
A UPC code doesn't contain characters, store them in a packed numeric field
even though the word "number" doesn't appear in it's description. |
|
Author:
HansBoldt
|
|
2009-06-09 10.44.50 |
Perhaps this is just a semantic game.
An id may consist of a string of digits. But that doesn't make the string a
"number" in the mathematical sense.
Could a decimal numeric field store my driver's license "number"? No, it begins
with the letter "B". Could a decimal numeric field store my OHIP "number"? No,
it ends with a couple of letters. You might be able to get away with numeric
type to store some forms of id "number". But it won't work in the general case.
|
|
Author:
CurtisB
|
|
2009-06-09 08.57.48 |
To say that the bank account number is not a number is a semantic game. If it is
not a number, you still have to move its parts to a numeric field or overlay it
with a data structure containing numeric fields to do the calculation. If the
field consists of only numbers, and you use those numbers in calculations, then
it is a numeric field, whether or not we normally use the entire number in a
numeric calculation. (If it walks like a duck...)
It is a little late to be concerned about how big RPG has gotten. It is a large
language. It is too late to make it a "pure" language without "improving" it out
of general use, or even existence. You may as well at least make changes that
are consistent with changes already made, which TFisher is recommending.
Niklaus Wirth created Pascal, which was wildly popular. He then improved Pascal
into Modula, then improved Modula into Oberon. No conversion programs were ever
provided, and each language became less and less popular. Component Pascal is a
.NET language, but a marginal one. Each iteration he made may have been better;
but he improved it out of general use.
At this point, there's no point in trying to "improve" RPG by ignoring the real
world's use of data. |
|
Author:
TFisher
|
|
2009-06-09 06.29.02 |
jacobus
You haven't been following this thread...I have my own procedure called
prSubstNumeric(). Again, my point is that everyone does it different and
there is no real consistency.
You haven't said anything that Hans hasn't already said and I still disagree.
If there is an argument that supports the existence %SUBDT then there must be
an argument that supports the need for %SUBNM.
Any value that must contain all digits should be stored in a numeric field,
packed decimal perferably. This is the rule that I have followed for over 24
years and often times developers do NOT get to pick field-types for third
party database files. We also must remember that there are companies doing
things differently than we do it and doing things that we probably have never
even seen (IBM really should remember this).
When we are required to look at say positions 5 and 6 of a 6-digit field we
should be able to do this:
Year = %SubNm(XXDate:5:2);
Take the requirement to calculate a check digit, If we had %SUBNM everyone's
code would look very similar and I would expect the program to be a bit more
effecient since we would not be switching between data types. I have seen a
couple of programs that calculate a check digit and they look very different
from each other even though they do the same thing. Take a look at what
it "could" look like:
D ChkDigit s 3p 0
D Sum s 3p 0
// Add the odd digits
For x = 1 to 11 by 2;
Sum = Sum + %SubNm(SKU:x:1);
Endfor;
ChkDigit = Sum * 3;
Sum = 0;
// Add the even digits
For x=2 to 10 by 2;
Sum = Sum + %SubNm(SKU:x:1);
Endfor;
ChkDigit = ChkDigit + Sum+1;
Dow %SubNm(ChkDigit:3:1) > 0;
ChkDigit = ChkDigit + 1;
Enddo;
If %SubNm(ChkDigit:1:1) > 0;
ChkDigit = %SubNm(ChkDigit:1:1);
Elseif %SubNm(ChkDigit:2:1) > 0;
ChkDigit = %SubNm(ChkDigit:2:1);
Else;
ChkDigit = %SubNm(ChkDigit:3:1);
Endif;
// ChkDigit now contains the check digit.
And there are many different types of check digits that differnet corporations
have to deal with...dates and times are still stored in numeric fields...SSN
may be stored in payroll systems in numeric fields...and this is only what I
know about.
What about the few routines that process amounts? For example, a program that
prints checks must convert '16344.56' to words. I wrote a procedure that
converts a numeric value to words a few years ago. It would have been much
easier if IBM had implemented a %SUBNM when they built %SUBST or when they
built %SUBDT.
Again, if there is a case for %SUBDT to exist in RPG then there must be a case
for %SUBNM to also exist. |
|
Author:
jacobus
|
|
2009-06-09 03.54.55 |
T,
I agree with Hans, it's about having a "types" language, RPG where each variable
has a specific type. You could introduce something like %subnm whihc treats a
numeric value as if it's numeric, but then why not simply make all variables
strings like Javascript?
%SUBST operates on strings.
A string is a sequence of characters, so you have parameters like "position" and
"lenth".
%SUBDT operates on dates.
A date consists of day/month/year, so youo have parameters like "*day", "*month"
etc.
%SUBNM would operate on numeric, but would have parameters like "position" and
"length" which make no sense for numerics.
In case of an id, such as a bank account, it is in fact a string (although
consisting of digits only). You don't do any calculations. Testing for modula-11
is not a calculation on the bank account. It is a test of the backaccount-string
and the implementation of this test happens to involve calculations.
If you really want something like %SUBNM why not make a procedure for this in a
serviceprogram, like SubNum. Introducing yet another %bif because it saves some
keystrokes only convolutes the already convoluted RPG language.
|
|
Author:
TFisher
|
|
2009-06-08 09.30.03 |
I may not be as smart as most, but I have to disagree that storing a NUMERIC
value in a NUMERIC field is NOT fundamentally wrong. We've also use packed
numeric fields over the years to store this information because it's more
effecient.
Again, some of our numeric values that we need to substring on are dates (we
don't use many ISO date fields due to (1) legacy code and (2) due to their
inefficiencies). So unless you somehow consider these IDs, this doesn't fit
into your agrument against a SUBSTRING-NUMBER.
|
|
Author:
HansBoldt
|
|
2009-06-08 08.52.49 |
Well, it's been a long time since I had any influence in the design of the RPG
language. But here's my point: As I've argued, using numeric type to store id's
is fundamentally wrong. Why should RPG development encourage the practice with a
built-in specifically targeted for such id's? Especially considering that
relatively easy alternatives already exist.
|
|
Author:
DaleB
|
|
2009-06-08 08.37.50 |
I see their point, Hans. Extracting digits with %EDITC and %SUBST is ugly. You
can still use a DS with OVERLAY to extract the digits, but you could make that
argument for character fields as well. %SUBST is redundant, but that doesn't
mean it isn't incredibly useful. For the same reasons, %SUBDT is redundant with
%SUBST(%CHAR), which is in turn redundant with DS and OVERLAY. Yet %SUBST and
%SUBDT exist, so why not %SUBNM? |
|
Author:
TFisher
|
|
2009-06-08 08.32.29 |
Hans,
I think we all have a technique that works, you echoed what I said...there are
a few ways to do it and from what I've seen here, everyone does it
differently. And, some of the techniques cannot be that effecient when
extracting each digit to calculate the check digit.
Why does everyone do it differently? Because the lack of a %SUBST-Number
solution! This only proves my point, that we need one! You haven't changed
my mind...
|
|
Author:
HansBoldt
|
|
2009-06-08 08.11.41 |
If you want to extract a digit out of a numeric variable, you can do something like:
eval digit = %subst(%editc(id:'X'):pos:1);
Alternatively, define a zoned numeric subfield to store the id, and overlay a
1S0 array.
There are lots of ways to do what you want today.
|
|
Author:
neilrh
|
|
2009-06-08 07.23.35 |
Same is true for things like EAN & UPC - there's a check digit, and the
ability to use something like %subnm would e a great help when validating that
check digit. |
|
Author:
CurtisB
|
|
2009-06-05 23.23.01 |
In this same vein, at the bank where I work, social security numbers are stored
in packed numeric fields and we have account numbers of all sorts, for all types
of accounts and credit and debit cards. The numbers in almost all cases are
given a check digit at creation by doing calculations over the remaining digits.
In fact, the numbers MUST be numeric in order to be created with the check
digit, and some account validation must sometimes be done using the check digit,
especially on credit card and debit card numbers. So in fact the numbers are
stored numerically, often in packed fields; if they were stored alphanumerically
on some file, each digit would still have to be moved to a numeric field to
enable the calculation.
So while is true that they are usually handled as though they are alphanumeric,
at some level calculations would be performed on them. |
|
Author:
TFisher
|
|
2009-06-05 17.03.37 |
neil,
I have already stated my opinion about international phone numbers and postal
codes, and they should be stored in character fields. This doesn’t mean that
all systems store these values in character fields. Our zip codes are stored
in character fields and phone number in numeric fields. It's not about how a
field should have been defined, it's about supporting the systems that are in
place today.
Hans,
I am not talking about doing mathematical operations, I am talking about
needing the ability to easily extract or process only a portion of a NUMERIC
value.
I agree that these are IDs, they are IDs that must be digits only. Therefore,
packed decimal field type were used for these fields. I also agree with the
developer's decision to use the data type that was best suited for the value
being stored. I disagree with IBM's decision not to provide a built-in
function for numeric data type.
I live and work in the real world, and in my real world we have social
security NUMBERS and credit card NUMBERS and other pieces of business data
(salesman and region codes, SKU and UPC numbers, color codes, stored in
NUMERIC fields that we are expected to process. I realize that the need to
parse a numeric value or create a numeric value from other values isn’t as
popular, or common, as character data, but we do it (and everyone does it
differently).
Oracle allows SUBSTR(SSN, -4) to get the last four digits of SSN.
Again, they gave us the %SUBDT function to offer the same functionality for
date/time field types that %SUBST offers for character fields. But many
systems still use numeric field types to store date and time values. It would
have been nice if they had thought of that.
|
|
Author:
neilrh
|
|
2009-06-05 12.33.53 |
And if you go international those numbers also might not be numeric - UK
version of the ssn is also 9 character long, but first 2 and last 1 are alpha. |
|
Author:
HansBoldt
|
|
2009-06-05 12.24.42 |
T: How often do you have to add some quantity to a SSN? Or take the square root
of a credit card number? No, these are not numbers. These are ids, which just
happen to be represented using digits.
|
|
Author:
TFisher
|
|
2009-06-05 12.12.11 |
Tom,
Yes, there are plenty of "work around" techniques. This was my point! The
language provides a solution, a technique, a function that is implemented for
only character data types. What about date and numeric functions!? It's like
IBM says "oh, let them figure it out for themselves".
Sure, we are smart enough to come up with our own techniques for taking
functions like %SUBST and creating something that works the same for other
data types. They even came back and later added %SUBDT. Why have they still
not given us a %SUBNM?
Wouldn't something like this:
SSN4 = %SUBNM(SSN : 6 :4);
be much easier to code and read than any other technique we have to use today?
I have been programming long enough to know that if I provide a function that
works for one data type, it wouldn't take much effort in most cases to clone
that function and ofter the same functionality for another data type. |
|
Author:
tomholden
|
|
2009-06-05 11.12.12 |
ugly but works:
dssn s 9s 0 inz(123456789)
dreplacevalue s 3a inz('023')
/free
ssn = %Dec(%subst(%EditC(ssn:'X'):1:5) + replacevalue
+ %subst(%EditC(ssn):'X'):9:1):9:0);
*Inlr=*on;
return;
LOL...just had to do it... |
|
Author:
TFisher
|
|
2009-06-05 11.02.35 |
Hans,
I would agree that phone numbers should be character, especailly international
phone numbers. Perhaps even international zip codes (postal codes). But
other examples are valid numeric data examples (how many characters are in
your SSN or credit card?).
The fact is that in MANY systems these fields are numeric and that demands we
process numeric data. If I want, or need, to substring part of a numeric
value then I need to be able to do it. |
|
Author:
HansBoldt
|
|
2009-06-05 10.35.04 |
T: Just because a particular piece of data consists of just digits, that doesn't
mean numeric is the appropriate representation. All the examples you listed
(phone number, zip code, credit card number, ssn) are all more appropriately
represented as character data, not numeric.
That is, if you need to do substringing on some data, use character type. If you
need to do arithmetic on the data, use numeric type. |
|
Author:
TFisher
|
|
2009-06-05 08.59.18 |
The problem with limiting functions to a certain data type is just that, it's
limitied...a partial implementation of a function. Now, I don't have a
problem with that "if" the same functionality is provided for other data types
(like was finally done for %SUBST for date data types, but we still don't have
%SUBST for numeric data types!).
Just as the SUBST operation and %SUBST BIF are limited, any %LEFT and %RIGHT
function that didn't support both character and numeric data type would also
be incomplete and would have developers having to work around the limitations.
Obviously these functions should support character data types, but we also
have the need to process numeric data...even if each function is replicated
for each of the data types (ie- %SUBST, %SUBDT and %SUBNUM for numeric data
type)
// Get the area code from a 10-digit phone number
AreaCode = %Subst(Phone :1 :3);
// Get the 5-digit zip code out of a 9-digit zip code
ZipCode = %Subst(Zip9 :1 :5);
// Get the check digit from the last digit of the card number
ChkDigit = %Subst(CrdCard :%Size(CrdCard) :1);
// Get last 4-digits from SSN
SSN4 = %Subst(SSN : 6 :4);
I am sure there are hundreds or thousands of other examples of needing to
process certain digits, or groups of digits, within a numeric field.
Because of the limitation of %SUBST, our need to process numeric data, and our
desire to avoid creating overlaying data structures or character work fields,
I created a prSubstNumeric() procedure. One nice feature is that for
the 'start position' it allows a keyword of *FIRST to specify that the
function should start at the first digit that is not zero.
|
|
Author:
neilrh
|
|
2009-06-05 07.45.26 |
I would've preferred EVAL %left/%right to our EVAL/EVALR. But we're done
there. |
|
Author:
HansBoldt
|
|
2009-06-05 07.42.10 |
Curtis: Now, you're bringing up one of the goofier aspects of MOVE and MOVEL,
the ability to mix characters and numerics in one move. Does anyone today
seriously think that's a good idea?
Regarding %LEFT and %RIGHT, I see no problem in limiting those to character or
DBCS type.
|
|
Author:
CurtisB
|
|
2009-06-04 21.10.13 |
Hans: I kind of figured conversion wasn't high on the list of priorities. That's
why I said that may not have been much of a factor in the decision-making process.
I thought MOVE FIELD1 FIELD looked like CHAIN KEY MASTER. I guess your
concept of freeform syntax is a little more refined than mine, and you would
know better.
I am actually not wedded to the idea of using MOVE as an opcode. Your idea of saying
EVAL %LEFT(TARGET) = SOURCE;
seems perfectly valid. I do foresee one possible problem, though. I believe that
when you use EVAL or EVALR, a numeric result must be developed from one or more
numeric expressions, and an alphanumeric result must be made up of alphanumeric
parts. Of course, in fixed format you can MOVE NUM1 ALPHA2 and MOVE ALPHA3
NUM4; it then becomes the programmer's responsibility to make sure the result is
not garbage. To truly replace MOVEL, we would have to allow TARGET and SOURCE to
be different data types. I'm not sure IBM would go for creating an inconsistent
rule, even for our %LEFT and %RIGHT BIFs.
Perhaps EVALM? |
|
Author:
HansBoldt
|
|
2009-06-04 14.29.01 |
Curtis: Most bloggers sign their name to their postings. I shouldn't have to
look up the whois record for a site to see who's behind a blog.
Anyhoo, I think you're missing one important point of /FREE that is often
forgotten. It was expected that it would be used mainly for new code. It was
never really intended for the conversion of old code.
Sure, conversion tools do exist. But (rightly or wrongly) it was felt at design
time that a clean free-form syntax should not be compromised for the sake of
ease of conversion. Some of the 3rd party conversion tools, though, are pretty
good, using the attributes of the variables in deciding how to convert.
On the other hand, it wouldn't surprise me if the RPG development team felt the
pressure to implement MOVE and MOVEL in free-form calcs. In my opinion, that
would be a mistake. If they wanted to make things easier, it should be in a
manner consistent with the free-form syntax. For example, I could envision LHS
BIF's, such as %LEFT and %RIGHT, used as in the following:
EVAL %LEFT(TARGET) = SOURCE; // acts like MOVEL
EVAL %RIGHT(TARGET) = SOURCE; // acts like MOVE
These would be a little easier, more flexible and more reliable, than coding:
EVAL %SUBST(TARGET:1:%LEN(SOURCE)) = SOURCE;
EVAL %SUBST(TARGET:%LEN(TARGET)-%LEN(SOURCE)+1) = SOURCE;
(If you want to suggest these BIF's to IBM, please feel free to take credit!)
|
|
Author:
CurtisB
|
|
2009-06-04 12.50.06 |
I am probably the blogger Hans was referring to (www.rpgandprogramming.com) . I
actually linked to this forum thread in my blog entry. I am a regular lurker in
this forum because of the interesting and informative discussions here.
I wonder if Hans may have missed my point. It would not be surprising if MOVE(L)
appears in my train of thought. From 1979 until I started using RPGIV in the
late 1990's, my options were limited, and MOVE(L), MOVEA, arrays, and data
structures were my main options for data, especially string, manipulation.
But I very seldom use MOVE these days, except for one-line changes in code
already riddled with MOVEs. I haven't for years. My point was not regarding the
value of MOVE, or even its power, but rather its ubiquity.
For many years, MOVE was the main option for moving data. We had little else to
work with, and so you will find MOVE in almost all programs before RPGIV, and
many since. And they work nicely.
This thread is about converting to freeform, particularly automatic conversion.
It's going to be done with some automation involved. (I'm not sure I'd want to
hire a programmer who insisted on converting a program with 1000 lines of
fixed-format calculations to freeform by hand.) Not implementing MOVE/MOVEL in
freeform seriously impacts the effectiveness of the conversion. If MOVE is not
transliterated into freeform, a human will almost certainly have to do the
conversion by hand; considering that there are no doubt millions of MOVEs around
(if not tens of millions), that will take a lot of time. If MOVE was used in
freeform, anyone who still had objections could have dealt with the MOVEs after
a relatively clean conversion.
It just seems like someone let their ideological objections to the opcode
override the practical value of a clean conversion. As it is, the conversion is
harder whether EVAL is better than MOVE or not. Of course, that may not have
been much of a factor in the decision-making process.
|
|
Author:
neilrh
|
|
2009-06-04 08.26.21 |
Interesting point. Yes I have seen code along the lines of...
MOVEL CHAR3 TEMP10
MOVE CHAR7 TEMP10
MOVEL TEMP10 RESULT20
MOVE CHAR10 RESULT20
Or the more common DS with 3 subfields (3,7,10 respectively) and moves to
those subfields - along with me paging back and forth between the I-specs (or
maybe D's if they done the RPGIV conversion) and C-Specs, trying to figure out
what field ends up where in the result field. The good thing about substring
is it keeps in all in the same place, and is numerically obvious what ends up
where. |
|
Author:
HansBoldt
|
|
2009-06-04 08.10.06 |
First, as some of you might know, I spent the last 4 years of my IBM career
working on the z/Series, an experience that was a little less than totally
enjoyable. What struck me when learning the z/Architecture was how much the
S/360 influenced the design of RPG II and CPF. Consider the MOVE/MOVEL opcodes.
These could be implemented fully using the MVC instruction. But that's not what
I want to discuss here.
Actually, I'm prompted to comment on the MOVE/MOVEL versus /FREE issue because
of comments made by some anonymous blogger posted elsewhere. What he/she wrote
isn't relevant. It just illustrates how ingrained these opcodes are in the
thinking of many RPG programmers.
What exactly do MOVE (and MOVEL) do? Let's just consider the cases of source
shorter than target. These opcodes do a right-adjusted (or left-adjusted) move
of the source into a portion of the target. As Bob rightly pointed out, that's
equivalent to having a %SUBST on the left-hand side of an EVAL assignment, which
clearly requires more coding.
But consider the coding needed without EVAL to assign into a substring that's
not at the right end (or left end) of the target? Is there an easy way to do it?
Most programmers would implement it using overlapping data structure subfields,
which of course, takes more coding effort than assigning into %SUBST.
This raises another point about MOVE and MOVEL. Since you're potentially not
modifying the entire result, it may not always be clear what value ends up in
the result after the opcode is done. Understanding the semantics of a particular
MOVE (or MOVEL) requires an understanding of the definitions of the variables
involved.
Let's go a bit further. Let's say you can't use EVAL and want to assign into a
substring of a target variable such that the start position and/or length are
variable. How do you code that without EVAL %SUBST? Frankly, I don't even want
to think about the RPG code needed for that!
What's my point? Sure, without MOVE/MOVEL in /FREE, some particular forms of
substring result coding need a bit more coding. However, in the general case of
substring result assignment, coding is much much easier. Given the additional
capabilities and advantages offered by /FREE coding, I find it hard to
sympathize with those who insist on clinging to older coding techniques.
|
|
Author:
Rocky
|
|
2009-05-29 16.22.03 |
Depends on what you mean by implement /free. I didn't start coding in RPG IV
until /free became available and I do all new coding in /free. Convert
programs that I will be spending appreciable amount of time modifying. However
I don't see us being an RPG IV shop, let alone a /free shop for a very long
time for various reasons. |
|
Author:
Bob Cozzi
|
|
2009-05-29 14.05.45 |
Yes EVALR came later after arguing with George F. over the implementation
(I probably continued by trend of making "friends" at that point--but at least
its implemented the way it should be.)
The MOVE/MOVEL issue is really one of functionality. Not that folks want to use
MOVEL instead of EVAL, but rather the integrated substring capabilities in
MOVE/MOVEL that requires explaining how to do the same task in /free (which is
supposed to be "better") is rather complicated. Certainly a simple tweak of
%SUBST would have solved the problem:
Instead of:
MOVEL REGION TARGET
We have to do this:
eval %subst(target:1:%len(target)) = target;
The EVAL charVar = %char(Custno) is clear enough and I think widely accepted.
But that substring thing is just a pain to a newbie /Free coder.
Perhaps a simple opextender would solve the issue:
eval(n) target = region; // Only replace r-value's length in target.
But that's water under the bridge. |
|
Author:
HansBoldt
|
|
2009-05-29 12.55.12 |
Well, once the decision was made to limit the opcodes, the general principle was
whether or not an "Extended-Factor-2" equivalent already existed. If so, the
fixed-form op was not to be included.
There were some exceptions. GOTO was considered "harmful", and so was excluded.
Also, we didn't yet have free-form equivalents of a couple of opcodes, like
LOOKUP and KLIST. For some of these, we added a couple of new built-in
functions. For KLIST, we just decided to wait until a future release for a
solution. We weren't quite sure what it would look like, but at least we felt
that opcodes were not the way to go for that.
Regarding MOVE and MOVEL, it always amazes me how attached some people are to
those particular opcodes. Certainly, the right-adjustment of MOVE was popular,
and that's what motivated EVALR. (That WAS implemented after /FREE, right?) But
otherwise, since the default behavior is to not blank fill the result, it's hard
to see how these opcode can be missed given the other options available by
free-form opcodes.
|
|
Author:
Bob Cozzi
|
|
2009-05-29 12.39.29 |
LOL! Me too.
Care to say why the MOVE/MOVEL were left off /free?
I mean, just the MOVE/MOVEL not the date stuff it currently does which was
moved to other things. |
|
Author:
HansBoldt
|
|
2009-05-29 12.27.12 |
Bob: You're asking me to try to remember something from a decade ago! For coding
alone, there couldn't have been more than about 1PM of effort in all. Of course,
the design took longer than anything, and there were a couple of reworks of the
design.
At the time, we first had a pretty big estimate for the work needed to implement
free-form calcs. This was reflected in our enhancement surveys, which typically
gave a cost of 100% for that. Well, I got to thinking about it, and I realized
that the only changes needed were in the parsing phase. If that could produce
identical intermediate text to what was already generated, the other phases
wouldn't know the difference.
I also realized that, with the current level of the language and current best
practices, we didn't have to implement all fields of the calc spec. That is,
control level, conditioning indicators, field length, and resulting indicators
didn't need a free-form equivalent. This would simplify design and implementation.
My first design for the syntax included all opcodes. Others on the team didn't
agree to that. I argued that that was necessary for acceptance. But some others
(one in particular) argued vociferously to the contrary. I soon realized he was
right. That design point meant we didn't have to worry about those goofy
multi-part factors.
Coding was fairly straight-forward. The calc-spec parsing module needed no more
than a couple hundred lines of C code.
Franky, looking back, considering the controversy at the time, I'm rather
surprised that the enhancement made it through to release.
|
|
Author:
Bob Cozzi
|
|
2009-05-29 11.36.02 |
Hans,
How long (in days) did it take you to implement /Free?
I mean just the coding, for the most part, not the other things that were
necessary to being it out. I want to include this in my paper on /Free (but I
won't mention you directly, unless you want me to). |
|