Home > Archive > Cobol > October 2007 > So, what about PERFORM...VARYING ?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
So, what about PERFORM...VARYING ?
|
|
| Pete Dashwood 2007-10-22, 3:55 am |
| OK, now that we've explored IF NUMERIC and data validation, how about this:
Here's some code I wrote today. It has to sort a table in memory into
descending order...
*> now sort the table of table names into descending order...
if K is positive *> K has the number of table entries in it...
perform
varying totn-x1
from 1
by 1
until totn-x1 > K
after L
from totn-x1 + 1
by 1
until L > K
if totn (L) < totn (totn-x1)
*> swap them (tournament sort...)
move totn (totn-x1) to temp
move totn (L) to totn (totn-x1)
move temp to totn (L)
end-if
end-perform
end-if
....
To my surprise (and chagrin :-)) Fujitsu complained bitterly about this.
Apparently, you can't use AFTER in an inline perform. Also, you can't use an
arithmetic expression (totn-x1 + 1) as a start value (following FROM).
I reckon that sucks. :-)
My single piece of code now has to be split into an out-of-line PERFORM so I
can use AFTER, and I have to do some ludicrous computing to ensure that the
inner loop starts in the right place...
Here's the revised code... (J thru N are just general purpose subscripts I
use in all my stuff...totn-x1 is an index associated with the
table-of-table-names)
*> now sort the table of table names into descending order...
if K is positive
move 2 to M
perform swap
varying totn-x1
from 1
by 1
until totn-x1 > K
after L
from M
by 1
until L > K
end-if
*------------------------------------------------------
swap section.
swap000.
if totn (L) < totn (totn-x1)
*> swap them (tournament sort...)
move totn (totn-x1) to temp
move totn (L) to totn-x1)
move temp to totn (L)
end-if
if L = K *> insane...:-)
set N to totn-x1 *> All because PERFORM
compute M = N + 2 *> can't do its job
end-if
| |
| William M. Klein 2007-10-22, 7:55 am |
| This was "fixed" (enhanced?) in the '02 Standard. Fujitsu conforms to the '85
Standard where you were NOT allowed to use AFTER for inline Perform. The
"solution" in the '85 Standard was to NEST inline performs. The following
SHOULD compile (and do what you want )with Fujitsu
if K is positive *> K has the number of table entries in it...
perform
varying totn-x1
from 1
by 1
until totn-x1 > K
Perform
Varying L
from totn-x1 + 1
by 1
until L > K
if totn (L) < totn (totn-x1)
*> swap them (tournament sort...)
move totn (totn-x1) to temp
move totn (L) to totn (totn-x1)
move temp to totn (L)
end-if
end-Perform
end-perform
End-If
the general "consensus" was that this was a STUPID restriction (and it was
removed in the '02 Standard) but if you have a "strictly conforming" (for this
syntax) '85 Standard compiler, then you need to use the "work-around".
--
Bill Klein
wmklein <at> ix.netcom.com
"Pete Dashwood" <dashwood@removethis.enternet.co.nz> wrote in message
news:5o2ln8Fkh1jeU2@mid.individual.net...
> OK, now that we've explored IF NUMERIC and data validation, how about this:
>
> Here's some code I wrote today. It has to sort a table in memory into
> descending order...
>
> *> now sort the table of table names into descending order...
> if K is positive *> K has the number of table entries in it...
> perform
> varying totn-x1
> from 1
> by 1
> until totn-x1 > K
> after L
> from totn-x1 + 1
> by 1
> until L > K
> if totn (L) < totn (totn-x1)
> *> swap them (tournament sort...)
> move totn (totn-x1) to temp
> move totn (L) to totn (totn-x1)
> move temp to totn (L)
> end-if
> end-perform
> end-if
> ...
>
> To my surprise (and chagrin :-)) Fujitsu complained bitterly about this.
>
> Apparently, you can't use AFTER in an inline perform. Also, you can't use an
> arithmetic expression (totn-x1 + 1) as a start value (following FROM).
>
> I reckon that sucks. :-)
>
> My single piece of code now has to be split into an out-of-line PERFORM so I
> can use AFTER, and I have to do some ludicrous computing to ensure that the
> inner loop starts in the right place...
>
> Here's the revised code... (J thru N are just general purpose subscripts I use
> in all my stuff...totn-x1 is an index associated with the
> table-of-table-names)
>
> *> now sort the table of table names into descending order...
> if K is positive
> move 2 to M
> perform swap
> varying totn-x1
> from 1
> by 1
> until totn-x1 > K
> after L
> from M
> by 1
> until L > K
> end-if
> *------------------------------------------------------
> swap section.
> swap000.
>
> if totn (L) < totn (totn-x1)
> *> swap them (tournament sort...)
> move totn (totn-x1) to temp
> move totn (L) to totn-x1)
> move temp to totn (L)
> end-if
> if L = K *> insane...:-)
> set N to totn-x1 *> All because PERFORM
> compute M = N + 2 *> can't do its job
> end-if
> .
> swap-exit.
> exit.
> *--------------------------------------------------------------------------------------------
>
> Can anyone tell me if this is just Fujitsu implementation, or does the
> Standard mandate it?
>
> IF the standard mandates it, any insights as to why?
>
> Pete.
> --
> "I used to write COBOL...now I can do anything."
>
| |
| Robert 2007-10-22, 7:55 am |
| On Mon, 22 Oct 2007 17:02:47 +1300, "Pete Dashwood" <dashwood@removethis.enternet.co.nz>
wrote:
>OK, now that we've explored IF NUMERIC and data validation, how about this:
>
>Here's some code I wrote today. It has to sort a table in memory into
>descending order...
>
> *> now sort the table of table names into descending order...
> if K is positive *> K has the number of table entries in it...
> perform
> varying totn-x1
> from 1
> by 1
> until totn-x1 > K
> after L
> from totn-x1 + 1
> by 1
> until L > K
> if totn (L) < totn (totn-x1)
> *> swap them (tournament sort...)
> move totn (totn-x1) to temp
> move totn (L) to totn (totn-x1)
> move temp to totn (L)
> end-if
> end-perform
> end-if
>...
>
>To my surprise (and chagrin :-)) Fujitsu complained bitterly about this.
>
>Apparently, you can't use AFTER in an inline perform. Also, you can't use an
>arithmetic expression (totn-x1 + 1) as a start value (following FROM).
>
>I reckon that sucks. :-)
>
>My single piece of code now has to be split into an out-of-line PERFORM so I
>can use AFTER, and I have to do some ludicrous computing to ensure that the
>inner loop starts in the right place...
>
>Here's the revised code... (J thru N are just general purpose subscripts I
>use in all my stuff...totn-x1 is an index associated with the
>table-of-table-names)
>
> *> now sort the table of table names into descending order...
> if K is positive
> move 2 to M
> perform swap
> varying totn-x1
> from 1
> by 1
> until totn-x1 > K
> after L
> from M
> by 1
> until L > K
> end-if
>*------------------------------------------------------
> swap section.
> swap000.
>
> if totn (L) < totn (totn-x1)
> *> swap them (tournament sort...)
> move totn (totn-x1) to temp
> move totn (L) to totn-x1)
> move temp to totn (L)
> end-if
> if L = K *> insane...:-)
> set N to totn-x1 *> All because PERFORM
> compute M = N + 2 *> can't do its job
> end-if
> .
> swap-exit.
> exit.
>*--------------------------------------------------------------------------------------------
>
>Can anyone tell me if this is just Fujitsu implementation, or does the
>Standard mandate it?
>
>IF the standard mandates it, any insights as to why?
You CAN use after in an inline perform. You cannot say " from totn-x1 + 1"
Changes to fix the first code:
1. This is the slowest sort algorithm known It will do K*K/2 comparisons. Since you don't
care about speed, change " from totn-x1 + 1" to "from totn-x1" The first iteration of the
inner loop will waste time comparing totn (L) to itself.
2. Change "until totn-x1 > K" to "until totn-x1 <= K" This is a bug.
3. Remove "if K is positive" If K is zero or 1, it won't do the sort anyway.
| |
| William M. Klein 2007-10-22, 7:55 am |
| Robert,
In which LRM for Fujitsu do you find that using AFTER with an INLINE perform
is allowed (as an extension to the '85 Standard)?
For Micro Focus (NE V5 LRM), they clearly document that the following as the '85
Standard rule,
"In Format 4, if procedure-name-1 is omitted, the AFTER phrase must not be
specified."
and then go ahead and document the MF extension (or ISO2002 change) with the
correct bubbles where it states,
This restriction does not apply."
***
The latest Fujitsu LRM that I have has no such extension (but I do not have the
latest one - so they MAY have added this as an extension within the last year or
so).
--
Bill Klein
wmklein <at> ix.netcom.com
"Robert" <no@e.mail> wrote in message
news:81coh39826glt651hf3gc0snpn8790d2l0@
4ax.com...
> On Mon, 22 Oct 2007 17:02:47 +1300, "Pete Dashwood"
> <dashwood@removethis.enternet.co.nz>
> wrote:
>
>
> You CAN use after in an inline perform. You cannot say " from totn-x1 + 1"
>
> Changes to fix the first code:
>
> 1. This is the slowest sort algorithm known It will do K*K/2 comparisons.
> Since you don't
> care about speed, change " from totn-x1 + 1" to "from totn-x1" The first
> iteration of the
> inner loop will waste time comparing totn (L) to itself.
>
> 2. Change "until totn-x1 > K" to "until totn-x1 <= K" This is a bug.
>
> 3. Remove "if K is positive" If K is zero or 1, it won't do the sort anyway.
| |
| Pete Dashwood 2007-10-22, 7:55 am |
|
"Robert" <no@e.mail> wrote in message
news:81coh39826glt651hf3gc0snpn8790d2l0@
4ax.com...
> On Mon, 22 Oct 2007 17:02:47 +1300, "Pete Dashwood"
> <dashwood@removethis.enternet.co.nz>
> wrote:
>
>
> You CAN use after in an inline perform.
Would you mind telling the Fujitsu NetCOBOL version 6 compiler that... It
won't listen to me... :-)
>You cannot say " from totn-x1 + 1"
Yes, I noted that. I also commented that it sucks...:-)
>
> Changes to fix the first code:
>
> 1. This is the slowest sort algorithm known
Maybe... it is also one of the easiest to implement in COBOL. :-)
>It will do K*K/2 comparisons.
No. If there were 10 entries, according to your formula, it would do 50
compares. In fact it will do the sum of : 10+9+8+7+6+5+4+3+2+1 which
(according to an algorithm derived by Friedrich Gauss when he was eight
years old, in response to being given an imposition which required adding up
the numbers from 1 to 100 (5050)) ... would mean 55 compares.
So? That's what computers are for... :-) At least everything gets compared
once only...and it gets quicker as it progresses :-)
As the table will probably never contain more than 10 entries, I really
don't care... :-)
>Since you don't
> care about speed, change " from totn-x1 + 1" to "from totn-x1" The first
> iteration of the
> inner loop will waste time comparing totn (L) to itself.
I don't think so. Look again. The inner loop compares the item at L to the
item at totn-x1 whenever it starts. As L is always 1 more than totn-x1
whenever the inner loop starts, it can never compare to itself.
>
> 2. Change "until totn-x1 > K" to "until totn-x1 <= K" This is a bug.
That would make it slightly more efficient as it doesn't need to do the last
compare. It isn't a bug, because it works as written. (and the table is
defined to hold more entries than K, so it does not give a subscript/index
error.)
The bug is that the compare in "swap" is the wrong way round :-) It's meant
to be a DESCENDING sort... :-)
>
> 3. Remove "if K is positive" If K is zero or 1, it won't do the sort
> anyway.
Yes, that's a good point. It was coded that way because K was originally
representing a range that started at zero, so If K was zero there would be 1
entry in the table and therefore no point in sorting anything. I have fixed
it.
Thanks for the comments Robert.
Pete.
--
"I used to write COBOL...now I can do anything."
| |
| Pete Dashwood 2007-10-22, 7:55 am |
|
"William M. Klein" <wmklein@nospam.netcom.com> wrote in message
news:tnWSi.149081$nh4.129091@fe09.news.easynews.com...
> This was "fixed" (enhanced?) in the '02 Standard. Fujitsu conforms to the
> '85 Standard where you were NOT allowed to use AFTER for inline Perform.
> The "solution" in the '85 Standard was to NEST inline performs. The
> following SHOULD compile (and do what you want )with Fujitsu
>
> if K is positive *> K has the number of table entries in it...
> perform
> varying totn-x1
> from 1
> by 1
> until totn-x1 > K
> Perform
> Varying L
> from totn-x1 + 1
> by 1
> until L > K
> if totn (L) < totn (totn-x1)
> *> swap them (tournament sort...)
> move totn (totn-x1) to temp
> move totn (L) to totn (totn-x1)
> move temp to totn (L)
> end-if
> end-Perform
> end-perform
> End-If
>
> the general "consensus" was that this was a STUPID restriction (and it was
> removed in the '02 Standard) but if you have a "strictly conforming" (for
> this syntax) '85 Standard compiler, then you need to use the
> "work-around".
>
Thanks Bill.
It never occured to me to nest the Perform... a bit ugly, but that's not a
bad workaround :-)
I've implemented it now and it works, so I won't change it, but I have
stored this information for future reference.
Thanks for clearing the position re Standard.
Pete.
--
"I used to write COBOL...now I can do anything."
| |
| Judson McClendon 2007-10-22, 7:55 am |
| "Pete Dashwood" <dashwood@removethis.enternet.co.nz> wrote:
> "Robert" <no@e.mail> wrote:
>
> Yes, I noted that. I also commented that it sucks...:-)
I've written production code in over 30 computer languages and dialects,
and COBOL is the only HLL I've used where <expression> cannot be
substituted anywhere a source variable can be used in procedural code.
It does indeed suck, and should have been fixed decades ago. Such
stick-in-the-mud thinking among those who write the COBOL standards
is a major reason COBOL is toast. Just look how long it took to be able
to use relative offsets in subscripting, and expressions weren't available
until very recently! Reference Modification should have been available
decades ago, and there are others, none of which detract from the many
desirable qualities of COBOL. These features were available in dozens
of other languages decades ago. Grrr! No wonder programmers used to
other languages have long seen COBOL as a dinosaur! 8-(
--
Judson McClendon judmc@sunvaley0.com (remove zero)
Sun Valley Systems http://sunvaley.com
"For God so loved the world that He gave His only begotten Son, that
whoever believes in Him should not perish but have everlasting life."
| |
| Robert 2007-10-22, 6:55 pm |
| On Mon, 22 Oct 2007 07:23:17 GMT, "William M. Klein" <wmklein@nospam.netcom.com> wrote:
>Robert,
> In which LRM for Fujitsu do you find that using AFTER with an INLINE perform
>is allowed (as an extension to the '85 Standard)?
>
>For Micro Focus (NE V5 LRM), they clearly document that the following as the '85
>Standard rule,
>
>"In Format 4, if procedure-name-1 is omitted, the AFTER phrase must not be
>specified."
Whoops. The syntax model appears to say you can do it, but the text contains the exact
same sentence.
| |
| William M. Klein 2007-10-22, 6:55 pm |
| "Pete Dashwood" <dashwood@removethis.enternet.co.nz> wrote in message
news:5o3c3vFksqf4U1@mid.individual.net...
<snip>
>
> Maybe... it is also one of the easiest to implement in COBOL. :-)
>
Pete,
As Fujitsu has not implemented the '02 Standard "table sort" feature, to me
the "easiest" way in COBOL to do a table sort (pre-02 Standard) is to use the
COBOL SORT verb/statement.
If you have an input procedure that "loops thru reading the table" and RELEASES
each table entry (and uses the "key" as the sort field) and then loops thru the
RETURNED values to fill the table, this seems "easy" to me. Depending on the
nature of the table (randomization), the SORT mechanism of the
compiler/run-time, and the size of the table, this may be anywhere from much
slower to much faster than SOME hand-crafted table sorts.
IBM even documents this approach for their mainframe users. See:
http://publibz.boulder.ibm.com/cgi-...3pg32/1.12.10.2
This is certainly NOT "the* solution for all users/programmers, but is one that
is easy to miss and does the job. (For a production program, I would certainly
TEST to see if its performance is or is not adequate.)
--
Bill Klein
wmklein <at> ix.netcom.com
| |
| William M. Klein 2007-10-22, 6:55 pm |
|
"Robert" <no@e.mail> wrote in message
news:nh7ph3dkv3saoq5ttgnpacv1r4thmumtsl@
4ax.com...
> On Mon, 22 Oct 2007 07:23:17 GMT, "William M. Klein"
> <wmklein@nospam.netcom.com> wrote:
>
>
> Whoops. The syntax model appears to say you can do it, but the text contains
> the exact
> same sentence.
>
You can "blame" the '85 Standard for the syntax diagram. Both MF and Fujitsu
based their diagram on what I Personally think was an AWFUL decision in the '85
Standard to try and force inline and out-of-line PERFORM variations into single
diagrams. You will notice (either LRM) that it LOOKS like you can have a
procedure-name-1 thru procedure-name-2 *and* an imperative-statement-1 in the
same PERFORM statement. Again, you have to read the syntax rules to find out
that this is a "no-no".
This diagram problem WAS "fixed" in the '02 Standard.
The bad diagram was actually how MF ended up with one of their extensions that I
(personally) HATE which is the extension allowing one to SOMETIMES (not always)
omit the END-PERFORM phrase at the end of an inline perform. When MF was first
implementing their '85 Standard support, they THOUGHT this was legal in the
Standard. By the time they figured out that it wasn't they had users using the
extension.
--
Bill Klein
wmklein <at> ix.netcom.com
| |
| HeyBub 2007-10-22, 6:55 pm |
| William M. Klein wrote:
> Pete,
> As Fujitsu has not implemented the '02 Standard "table sort"
> feature, to me the "easiest" way in COBOL to do a table sort (pre-02
> Standard) is to use the COBOL SORT verb/statement.
>
> If you have an input procedure that "loops thru reading the table"
> and RELEASES each table entry (and uses the "key" as the sort field)
> and then loops thru the RETURNED values to fill the table, this seems
> "easy" to me. Depending on the nature of the table (randomization),
> the SORT mechanism of the compiler/run-time, and the size of the
> table, this may be anywhere from much slower to much faster than SOME
> hand-crafted table sorts.
> IBM even documents this approach for their mainframe users. See:
>
> http://publibz.boulder.ibm.com/cgi-...3pg32/1.12.10.2
>
> This is certainly NOT "the* solution for all users/programmers, but
> is one that is easy to miss and does the job. (For a production
> program, I would certainly TEST to see if its performance is or is
> not adequate.)
SORT is good.
Another is to put the records in an off-screen ListView box, sort by column,
then read the LV box back into the array.
About six statements.
| |
| Howard Brazee 2007-10-22, 6:55 pm |
| On Mon, 22 Oct 2007 00:29:35 -0500, Robert <no@e.mail> wrote:
>1. This is the slowest sort algorithm known It will do K*K/2 comparisons. Since you don't
>care about speed, change " from totn-x1 + 1" to "from totn-x1" The first iteration of the
>inner loop will waste time comparing totn (L) to itself.
Since I don't have a compiler that will do internal CoBOL sorts (why
hasn't this been available since sort was invented?), I use a comb
sort.
Basically once code like this is written once, it can be cloned or
better - so why not make it efficient?
I never have had occasion to want to put AFTER in a block perform, but
I have nested them. Block performs tend to be relatively straight
forward.
| |
| Judson McClendon 2007-10-23, 7:55 am |
| "Pete Dashwood" <dashwood@removethis.enternet.co.nz> wrote:
> "Judson McClendon" <judmc@sunvaley0.com> wrote in message news:LG5Ti.4510$c9.379@bignews8.bellsouth.net...
>
> No, it is the FCL, if you're going to be pedantic...:-) Besides, those are C# constructs so it IS C# doing it; if it were .NET
> COBOL I would need to format the statements differently.
That's .NET FCL. :-)
C# merely compiles the code to invoke the Sort or Reverse methods
in the MyCollection object. It does not generate code to do the sort,
or even recognize that a sort is being done. How can you call that
C# "doing it?" :-)
>
> I rarely search the DotNET documentation any more; simply GOOGLE and get a code sample immediately... :-)
Thanks, I'll try that. :-)
--
Judson McClendon judmc@sunvaley0.com (remove zero)
Sun Valley Systems http://sunvaley.com
"For God so loved the world that He gave His only begotten Son, that
whoever believes in Him should not perish but have everlasting life."
| |
| Pete Dashwood 2007-10-23, 7:55 am |
|
"Judson McClendon" <judmc@sunvaley0.com> wrote in message
news:K4kTi.2440$m11.1557@bignews9.bellsouth.net...
> "Pete Dashwood" <dashwood@removethis.enternet.co.nz> wrote:
>
> That's .NET FCL. :-)
> C# merely compiles the code to invoke the Sort or Reverse methods
> in the MyCollection object. It does not generate code to do the sort,
> or even recognize that a sort is being done. How can you call that
> C# "doing it?" :-)
Because without the C# code it wouldn't happen, precisely as with COBOL. Now
stop being silly... :-)
>
>
> Thanks, I'll try that. :-)
> --
> Judson McClendon judmc@sunvaley0.com (remove zero)
> Sun Valley Systems http://sunvaley.com
> "For God so loved the world that He gave His only begotten Son, that
> whoever believes in Him should not perish but have everlasting life."
>
|
|
|
|
|