For Programmers: Free Programming Magazines  


Home > Archive > Cobol > January 2006 > Re: free implementation? factorial?









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 Re: free implementation? factorial?
charles hottel

2006-01-10, 3:55 am


"Nicolas Neuss" <firstname.lastname@iwr.uni-heidelberg.de> wrote in message
news:87lkxpgnwc.fsf@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...ae713b0615c1445>
>
> 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.


Chuck Stevens

2006-01-10, 6:55 pm


"charles hottel" <jghottel@yahoo.com> wrote in message
news:a9c14$43c31f96$4f9c6e7$32726@DIALUP
USA.NET...
>
> "Nicolas Neuss" <firstname.lastname@iwr.uni-heidelberg.de> wrote in
> message news:87lkxpgnwc.fsf@ortler.iwr.uni-heidelberg.de...
>
> <snip>
>
>
> 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


Howard Brazee

2006-01-10, 6:55 pm

On Tue, 10 Jan 2006 07:33:01 -0800, "Chuck Stevens"
<charles.stevens@unisys.com> wrote:

>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)?


I wouldn't be surprised if some compiler choked on this. But we can
certainly program recursive code anyway.
Oliver Wong

2006-01-10, 9:55 pm


"Chuck Stevens" <charles.stevens@unisys.com> wrote in message
news:dq0k3c$2dsd$1@si05.rsvl.unisys.com...
>
> 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)?


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>

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>

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.

- Oliver


charles hottel

2006-01-10, 9:55 pm


"Chuck Stevens" <charles.stevens@unisys.com> wrote in message
news:dq0k3c$2dsd$1@si05.rsvl.unisys.com...
>
> "charles hottel" <jghottel@yahoo.com> wrote in message
> news:a9c14$43c31f96$4f9c6e7$32726@DIALUP
USA.NET...
>
> 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
>


Well I remember trying it with IBM mainframe COBOL and IIRC it resulted in
an infinite loop.


Chuck Stevens

2006-01-10, 9:55 pm


"Oliver Wong" <owong@castortech.com> wrote in message
news:mnRwf.73044$OU5.13400@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


charles hottel

2006-01-10, 9:55 pm


"Chuck Stevens" <charles.stevens@unisys.com> wrote in message
news:dq0k3c$2dsd$1@si05.rsvl.unisys.com...
>
> "charles hottel" <jghottel@yahoo.com> wrote in message
> news:a9c14$43c31f96$4f9c6e7$32726@DIALUP
USA.NET...
>
> 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.


charles hottel

2006-01-10, 9:55 pm


"charles hottel" <jghottel@yahoo.com> wrote in message
news:b5912$43c3f2d2$4f9c6bb$4276@DIALUPU
SA.NET...
>
> "Chuck Stevens" <charles.stevens@unisys.com> wrote in message
> news:dq0k3c$2dsd$1@si05.rsvl.unisys.com...
>
> 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.


Chuck Stevens

2006-01-10, 9:55 pm

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


Karl Kiesel

2006-01-11, 3:55 am

"Chuck Stevens" <charles.stevens@unisys.com> schrieb im Newsbeitrag
news:dq0q64$2hee$1@si05.rsvl.unisys.com...
>...
> 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.


what about STD 1985, PERFORM general rule (14) (page VI-120)?

This rule does not distinguish between various types (directly, indirectly,
same, different,...) of PERFORM statements; thus it also applys to the case
where 'an active PERFORM statement' and 'another active PERFORM statement'
are the *same* statment! It also does not talk of passing *thru* an exit but
of 'allow control to pass *to* the exit of the other statement' and
explicitly states that 'two or more such active PERFORM statements may not
have *a common exit*'
For me this looks definitely as if overlapping (especially recursive)
PERFORM statements were not conforming to the standard. But since various
implementations have lifted these restrictions on perform statements, this
seems to have resulted in entry 37) of the undefined language element list
of STD 2002.

K. Kiesel


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com