From: Chuck Stevens on

"Oliver Wong" <owong(a)castortech.com> wrote in message
news:mnRwf.73044$OU5.13400(a)clgrps13...

> http://www.csis.ul.ie/COBOL/Course/Iteration.htm
> <quote>
> Although Netexpress does allow recursive Performs, this is a nonstandard
> extension. Please do not take advantage of it..
> </quote>
> <quote>
> Recursion not allowed.
> Although Performs can be nested, neither direct nor indirect recursion is
> allowed. This means that a paragraph must not contain a PERFORM that
> invokes itself or any ancestor paragraph (parent, grandparent etc).
> Unfortunately this restriction is not enforced by the compiler but your
> program will not work correctly if you use recursive Performs
> </quote>

OK, I still haven't found anything in ANSI X3.23-1974 or ANSI X3.23-1985 or
ISO/IEC 1989:2002 that leads me to believe that this restriction is anything
more than a caution against Bad Practice.

> http://docs.hp.com/cgi-bin/doc3k/B3150090014.11950/16
> <quote>
> Do not write an illegal program, even if it works on the first
> machine for which you are writing the program. It may not work
> the same way on another machine. (Examples of illegal things that
> may work differently on different machines are: branching out of
> PERFORM paragraphs, PERFORM statements with common exit points,
> and indirectly recursive PERFORM statements.)
> </quote>

This is a *directly* recursive PERFORM statement; the restriction isn't
relevant. I would say indirectly recursive PERFORMs can be *dangerous* (as
can branching out of a PERFORM range to a point that causes the PERFORM
itself to be re-executed) and should be regarded as "bad practice", but as
far as I can tell, they are not, strictly speaking, "illegal".

And while PERFORMs with common exit points may be Bad Style, so long as the
*execution-time* path leads to the common exit point, who cares? In fact,
PERFORM GR8 in the '85 standard makes rather a point of this: what the
PERFORM range actually consists of is an *execution-time* determination and
thus directly *permits* the practice: "If there are two or more logical
paths to the return point, then procedure-name-2 may be the name of a
paragraph consisting of the EXIT statement, to which all of these paths must
lead."

> My understanding of the behaviour of the PERFORM statement, though I
> cannot currently find documentation to back this up, is that there is no
> "call stack". Rather, each paragraph has a memory slot associated to it in
> which it stores the return address, so if a paragraph calls itself
> (directly or indirectly), one of the return addresses will get overwritten
> and thus lost.

That is an implementation detail. Unisys MCP systems use a different
approach, different enough, in fact, that the concept of any sort of "memory
address" is fairly foreign. *All* data and code addresses are
stack-relative, and data and code may disappear from one location and
reappear in another location in memory without any knowledge or intervention
by the program, and that includes the stack itself. True, there's no
separate "call stack"; it's the same stack that's used for evaluation and
for data addressing and everything else. The machine's built around it.
When a PERFORM is executed, a PCW pointing to the return point is put on the
stack, followed by a value identifying the end of the PERFORM range. At
each PERFORM range end point, code checks the value on TOS, and if it
matches, does a dynamic branch to the code address to which the PCW points,
and if it doesn't, preserves the value and the PCW and drops past the label.
It's always the most-recently-active PERFORM that gets checked. The limit
to which PERFORMs can be nested at execution time is an implementation
detail, and in our case the determining factor is "how much space do you
want your program's stack to take up at execution time?"

Again, I know full well that mucking with control flow during execution of a
PERFORM is frowned upon as Bad Practice, but I still haven't seen anything
that leads me to believe *any* COBOL standard expressly forbids it. If you
*eventually* get to the end of the PERFORM range, it looks to me like how
you get there, and what you do in the meantime, is irrelevant.

-Chuck Stevens


From: charles hottel on

"Chuck Stevens" <charles.stevens(a)unisys.com> wrote in message
news:dq0k3c$2dsd$1(a)si05.rsvl.unisys.com...
>
> "charles hottel" <jghottel(a)yahoo.com> wrote in message
> news:a9c14$43c31f96$4f9c6e7$32726(a)DIALUPUSA.NET...
>>
>> "Nicolas Neuss" <firstname.lastname(a)iwr.uni-heidelberg.de> wrote in
>> message news:87lkxpgnwc.fsf(a)ortler.iwr.uni-heidelberg.de...
>>
>> <snip>
>>
>>> I had found this one already, but had somehow hoped that a nicer version
>>> would be possible, e.g. something like in
>>>
>>> <http://groups.google.com/group/comp.lang.cobol/msg/fae713b0615c1445>
>>>
>>> Thank you,
>>>
>>> Nicolas.
>>
>> I do not think that the program at this link is valid COBOL. A COBOL
>> program can be recursive but COBOL paragraphs are not recursive at least
>> not in the compilers that I am familiar with.
>
> Hmmm. I don't have any problem with the following program using either of
> the COBOL compilers supported for the Unisys MCP systems ('74 and '85
> standards respectively):
>
> IDENTIFICATION DIVISION.
> ENVIRONMENT DIVISION.
> DATA DIVISION.
> WORKING-STORAGE SECTION.
> 77 FACT-RES PIC 9(8).
> 77 ARGUMENT PIC 9(8).
> PROCEDURE DIVISION.
> MAIN-LINE.
> MOVE 1 TO FACT-RES. MOVE 5 TO ARGUMENT.
> PERFORM COMPUTE-FACTORIAL.
> DISPLAY FACT-RES.
> STOP RUN.
> COMPUTE-FACTORIAL.
> IF ARGUMENT > 1
> COMPUTE FACT-RES = FACT-RES * ARGUMENT
> SUBTRACT 1 FROM ARGUMENT
> PERFORM COMPUTE-FACTORIAL.
>
> I've looked at the standards, and don't see anything that says PERFORMing
> a paragraph recursively is illegal (though a STACK OVERFLOW fault in a
> COBOL program on Unisys MCP systems is virtually diagnostic of
> re-executing a PERFORM without ever completing the PERORM range it is in,
> so such matters must be handled with care).
>
> Can you cite some documentation somewhere supporting the assertion that
> one can't PERFORM a paragraph from within the paragraph (whether or not
> that paragraph is also PERFORMed externally)?
>
> -Chuck Stevens

See
www.cs.vu.nl/~nveerman/research/minefield/minefield.pdf

Starting on page 5 this is discussed and some summaries from the manuals of
different COBOL vendors is given.


From: charles hottel on

"charles hottel" <jghottel(a)yahoo.com> wrote in message
news:b5912$43c3f2d2$4f9c6bb$4276(a)DIALUPUSA.NET...
>
> "Chuck Stevens" <charles.stevens(a)unisys.com> wrote in message
> news:dq0k3c$2dsd$1(a)si05.rsvl.unisys.com...
>>
>> "charles hottel" <jghottel(a)yahoo.com> wrote in message
>> news:a9c14$43c31f96$4f9c6e7$32726(a)DIALUPUSA.NET...
>>>
>>> "Nicolas Neuss" <firstname.lastname(a)iwr.uni-heidelberg.de> wrote in
>>> message news:87lkxpgnwc.fsf(a)ortler.iwr.uni-heidelberg.de...
>>>
>>> <snip>
>>>
>>>> I had found this one already, but had somehow hoped that a nicer
>>>> version
>>>> would be possible, e.g. something like in
>>>>
>>>> <http://groups.google.com/group/comp.lang.cobol/msg/fae713b0615c1445>
>>>>
>>>> Thank you,
>>>>
>>>> Nicolas.
>>>
>>> I do not think that the program at this link is valid COBOL. A COBOL
>>> program can be recursive but COBOL paragraphs are not recursive at least
>>> not in the compilers that I am familiar with.
>>
>> Hmmm. I don't have any problem with the following program using either
>> of the COBOL compilers supported for the Unisys MCP systems ('74 and '85
>> standards respectively):
>>
>> IDENTIFICATION DIVISION.
>> ENVIRONMENT DIVISION.
>> DATA DIVISION.
>> WORKING-STORAGE SECTION.
>> 77 FACT-RES PIC 9(8).
>> 77 ARGUMENT PIC 9(8).
>> PROCEDURE DIVISION.
>> MAIN-LINE.
>> MOVE 1 TO FACT-RES. MOVE 5 TO ARGUMENT.
>> PERFORM COMPUTE-FACTORIAL.
>> DISPLAY FACT-RES.
>> STOP RUN.
>> COMPUTE-FACTORIAL.
>> IF ARGUMENT > 1
>> COMPUTE FACT-RES = FACT-RES * ARGUMENT
>> SUBTRACT 1 FROM ARGUMENT
>> PERFORM COMPUTE-FACTORIAL.
>>
>> I've looked at the standards, and don't see anything that says PERFORMing
>> a paragraph recursively is illegal (though a STACK OVERFLOW fault in a
>> COBOL program on Unisys MCP systems is virtually diagnostic of
>> re-executing a PERFORM without ever completing the PERORM range it is in,
>> so such matters must be handled with care).
>>
>> Can you cite some documentation somewhere supporting the assertion that
>> one can't PERFORM a paragraph from within the paragraph (whether or not
>> that paragraph is also PERFORMed externally)?
>>
>> -Chuck Stevens
>
> See
> www.cs.vu.nl/~nveerman/research/minefield/minefield.pdf
>
> Starting on page 5 this is discussed and some summaries from the manuals
> of different COBOL vendors is given.
>
>

Page 5 also quotes the 2002 standard and says that recursive PERFORM
statements are NOT forbidden by the standard.


From: Alain Reymond on
Peter Lacey a ?crit :
> Alain Reymond wrote:
>
>>Nicolas,
>>
>>Try to use the recursive posssibilities of modern Cobol. This is good
>>for teaching and showing that Cobol is no more an amount of go to's in
>>spaghetti code (troll)...
>>
>
> Why teach the more complicated method first? This isn't a case where
> using recursion is preferable. Also (troll-reply) an instructor
> shouldn't get involved in religious wars unless that happens to be the
> course subject.
>
> PL

I should have added a smile!

the fact is that factorial is usualy the first approach to recursion
when teached to students.
As the other solution is quite easy, the aim was to show that an elegant
(I hope so!) solution also exists in Cobol using the same concepts as in
C or Pascal or java which probably are more teached to students than Cobol.

Regards.

Alain
From: Chuck Stevens on
THAT's the sort of thing I was looking for. The standard reference is
ISO/IEC 1989:2002 page 494, 14.8.27.3, PERFORM statement, General Rule 11:

"The results of executing the following sequence of PERFORM statements are
undefined and no exception condition is set to exist when the following
sequence is executed:

a) a PERFORM statement is executed and has not yet terminated, then

b) within the range of that PERFORM statement another PERFORM statement is
executed, then

c) the execution of the second PERFORM statement passes through the exit of
the first PERFORM statement. "

I'd contend that "passes through" is not the same thing as "terminates at".
I believe the circumstance being described here is that in which the PERFORM
terminus of the second is located such that the PERFORM terminus of the
first must be *passed through* to get to the remainder of the statements in
the second PERFORM range.

I'll file an "interpretation request" with J4 on this point, as I believe
the "recursive PERFORM" raises different issues from "PERFORMs with
overlapping execution ranges".

-Chuck Stevens


First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10
Prev: Data Representation in COBOL
Next: xml acucobol