0

I am currently learning Cobol language, and I wrote a paragraph with the following structure :

MYPARA. 
    EVALUATE TRUE       
       WHEN COND1           
          ...        
       WHEN COND2           
          ...           
          PERFORM MYPARA        
       WHEN OTHER           
          ...     
    END-EVALUATE 
    .

This is a recursion that works great, however I just learned that it must not be done because it can lead to unpredictable results ( In COBOL, is it possible to recursively call a paragraph? ). So is it impossible to have recursion within the same Cobol program ?

I thought about using an intermediary paragraph : MYPARA execute MYPARA2 and MYPARA2 execute MYPARA. Is it exactly the same or different for the compiler/execution ?

The execution works great, but it is clearly stated that a paragraph can't call itself. Any form of recursion between paragraph is possible or forbidden ?

In my case I could wrap the EVALUATE in a PERFORM UNTIL as an alternative to the recursion, but I really wanted to do it that way.

Korlek
  • 1
  • 1
  • 1
    Based on the link you provided, it's possible that a particular implementation of COBOL supports recursion. However, the overhead of recursive calls is pretty high compared to a PERFORM VARYING. – Gilbert Le Blanc Feb 10 '23 at 13:46
  • It depends on the implementation, but that may "work now" and if there are more calls later stop working. Also in debuggers you commonly won't have fun with the recursion either (a loop, which you can also fast-enter with `EXIT PERFORM` instead of rolling the complete stack back is really the way to go. – Simon Sobisch Feb 10 '23 at 14:07
  • Depending on your target platform, you might benefit from reading [this IBM COBOL page](https://www.ibm.com/docs/en/cobol-zos/6.3?topic=subprograms-making-recursive-calls). It describes how to make a PROGRAM recursively callable however (in a nutshell: just add RECURSIVE to the PROGRAM-ID paragraph), not a section or paragraph. I'm not sure this works for other COBOL implementations as well though. – Remko Feb 13 '23 at 08:16

1 Answers1

0

Recursion works for most languages and COBOL programs because the return location is pushed onto a stack before the call. When the program executes itself, a new return location is pushed. As each invocation of the program returns, the locations stored on the stack are popped off one-by-one, allowing the return instruction to resume execution at the right places.

For IBM COBOL, the Perform statement does not use a stack. Instead, each performed paragraph has a "resume" address for the end of the paragraph. Normally, this resume address points to the next paragraph. Each Perform statement has a "save" cell to save the target paragraph's resume address. When the perform happens, it copies the resume cell to the save cell, stores the address after the perform statement in the resume cell, then jumps to the paragraph. The end of the paragraph picks up the address in the resume cell and jumps to it, effectively returning to the address after the perform. The instructions there copies the save cell back to the resume cell, restoring the paragraph to the way it was.

This all works great until you realize that the "save" cell is a stack with the capacity of only one entry. This means if the same save cell is used again before a restore happens, the old value is wiped out. The resume cell will never have its old content back. The paragraph will not be able to return to where it supposed to return. The problem may not show up if overwriting does not occur because each perform statement has its own "save" cell. Thus, if we use "->" to represent "performs" and A & B are paragraphs, A->B->B works, but A->B->B->B will get you into an infinite loop when the outermost B is trying to return to A.

chieny
  • 1