COBOL Unbounded Loops A Diatribe On Their Omission From the COBOL Standard (and a Plea for Understanding)

Similar documents
Lesson 13 Transcript: User-Defined Functions

Repetition Structures

Lecture Transcript While and Do While Statements in C++

Condition-Controlled Loop. Condition-Controlled Loop. If Statement. Various Forms. Conditional-Controlled Loop. Loop Caution.

ITCS Implementation. Jing Yang 2010 Fall. Class 14: Introduction to SQL Programming Techniques (Ch13) Outline

About these Release Notes. This document contains important information about Pro*COBOL 12c Release 2 (12.2).

Copyright 2016 Ramez Elmasri and Shamkant B. Navathe

SOME TYPES AND USES OF DATA MODELS

CS252 Advanced Programming Language Principles. Prof. Tom Austin San José State University Fall 2013

APPENDIX B. Fortran Hints

Question Bank PL/SQL Fundamentals-I

G Programming Languages - Fall 2012

Oracle SQL. murach s. and PL/SQL TRAINING & REFERENCE. (Chapter 2)

Introduction to Programming

Chapter 13 Introduction to SQL Programming Techniques

Windows Script Host Fundamentals

About these Release Notes

Design First ITS Instructor Tool

COBOL - DATABASE INTERFACE

An Incomplete Language Feature

Database Applications. SQL/PSM Embedded SQL JDBC

Lesson 17 Transcript: Troubleshooting

Annotation Hammer Venkat Subramaniam (Also published at

COSC 2P91. Bringing it all together... Week 4b. Brock University. Brock University (Week 4b) Bringing it all together... 1 / 22

There are a number of ways of doing this, and we will examine two of them. Fig1. Circuit 3a Flash two LEDs.

1Z0-144 Q&As Oracle Database 11g: Program with PL/ SQL

Programming the Database

Programming Languages and Program Development Life Cycle Fall Introduction to Information and Communication Technologies CSD 102

Mainframe Tutorials Cobol Db2 Jcl Cics Tutorials

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #17. Loops: Break Statement

Java Programming Fundamentals - Day Instructor: Jason Yoon Website:

6.001 Notes: Section 17.5

Oracle PLSQL. Course Summary. Duration. Objectives

Lecture 01 & 02 Computer Programming

Read & Download (PDF Kindle) Programming: C ++ Programming : Programming Language For Beginners: LEARN IN A DAY! (C++, Javascript, PHP, Python, Sql,

Introduction to Visual Basic and Visual C++ Arithmetic Expression. Arithmetic Expression. Using Arithmetic Expression. Lesson 4.

Iteration. # a and b are now equal # a and b are no longer equal Multiple assignment

the Computability Hierarchy

Cursors Christian S. Jensen, Richard T. Snodgrass, and T. Y. Cliff Leung

Control Structures. Control Structures 3-1

GnuCOBOL Quick Reference

Review of the syntax and use of Arduino functions, with special attention to the setup and loop functions.

Introduction. A. Bellaachia Page: 1

Full file at

PROCEDURAL DATABASE PROGRAMMING ( PL/SQL AND T-SQL)

ORACLE: PL/SQL Programming

IBM DB2 9.7 SQL Procedure Developer.

Perl Basics. Structure, Style, and Documentation

COBOL for AIX, Version 4.1

Week 2: The Clojure Language. Background Basic structure A few of the most useful facilities. A modernized Lisp. An insider's opinion

An Alternative to Name Injection from Templates

Module 10A Lecture - 20 What is a function? Why use functions Example: power (base, n)

About these Release Notes. Documentation Accessibility. New Features in Pro*COBOL

Language Basics. /* The NUMBER GAME - User tries to guess a number between 1 and 10 */ /* Generate a random number between 1 and 10 */

Principle of Complier Design Prof. Y. N. Srikant Department of Computer Science and Automation Indian Institute of Science, Bangalore

8. Control statements

SQL-CMA SQL*XT for ORACLE

Contents I Introduction 1 Introduction to PL/SQL iii

Chapter 1 Introduction

Project 5 - The Meta-Circular Evaluator

Introduction to Computer Science and Business

These are notes for the third lecture; if statements and loops.

For Loop Exit Strategies (Revision 3)

Snowflake Numbers. A look at the Collatz Conjecture in a recreational manner. By Sir Charles W. Shults III

Database Management System Dr. S. Srinath Department of Computer Science & Engineering Indian Institute of Technology, Madras Lecture No.

How to approach a computational problem

T H E I N T E R A C T I V E S H E L L

Viewing the tm4c123gh6pm_startup_ccs.c file, the first piece of code we see after the comments is shown in Figure 1.

Control Structures. Important Semantic Difference

The compiler is spewing error messages.

1Z Oracle Database 11g - Program with PL/SQL Exam Summary Syllabus Questions

COS 140: Foundations of Computer Science

5. Control Statements

PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between

(Refer Slide Time: 01:12)

Section 1. The essence of COBOL programming. Mike Murach & Associates

ADVANTAGES. Via PL/SQL, all sorts of calculations can be done quickly and efficiently without use of Oracle engine.

1 Overview. 2 Basic Program Structure. 2.1 Required and Optional Parts of Sketch

Please click double click on the icon labeled Internet Explorer, the picture is a blue letter E.

Post Experiment Interview Questions

To figure this out we need a more precise understanding of how ML works

Lesson 11 Transcript: Concurrency and locking

A3 Computer Architecture

do fifty two: Language Reference Manual

Puppet Labs Modules - Feature #11050 firewall: RFE that ensure could support ignore.

Lesson 3 Transcript: Part 2 of 2 Tools & Scripting

LN #3 (3 Hrs) Repetition, Computational state CTPS Department of CSE,Coimbatore

COBOL performance: Myths and Realities

(Refer Slide Time: 1:36)

Extending static_assert

Evaluation of Visual Fabrique (VF)

Redvers Hashing Algorithm. User Guide. RCHASH Version 2.3

SQL STORED ROUTINES. CS121: Relational Databases Fall 2017 Lecture 9

UNIT I Programming Language Syntax and semantics. Kainjan Sanghavi

Using the PowerExchange CallProg Function to Call a User Exit Program

Product Review: James F. Koopmann Pine Horse, Inc. SoftTree s SQL Assistant. Product Review: SoftTree s SQL Assistant

Definition: A data structure is a way of organizing data in a computer so that it can be used efficiently.

Getting Started. Excerpted from Hello World! Computer Programming for Kids and Other Beginners

CSE 142 Su 04 Computer Programming 1 - Java. Objects

Sql Server Call Function Without Schema Name

Transcription:

COBOL Unbounded Loops A Diatribe On Their Omission From the COBOL Standard (and a Plea for Understanding) August 11, 2016 Frank Swarbrick Principal Analyst Mainframe Applications Development FirstBank Lakewood, CO USA Introduction The COBOL standard (as of 2014), and thus IBM Enterprise COBOL, do not support a natural syntax for an unbounded loop via the native looping mechanisms. Several other COBOL implementations have extended the language to provide this missing support. 1. Micro Focus and GnuCOBOL support a PERFORM FOREVER inline perform loop. 2. GnuCOBOL supports PERFORM UNTIL EXIT as well, with the same behavior. 3. Fujitsu COBOL supports PERFORM WITH NO LIMIT syntax with the same behavior. The Fujitsu Software NetCOBOL V11.0 User s Guide has this to say: WITH NO LIMIT must be specified for the PERFORM statement to prevent the system generating code to determine the at end condition. When PERFORM WITH NO LIMIT is specified, the group of statements is executed repeatedly until an explicit exit or transfer of control is encountered. When you use the NO LIMIT phrase you must include statements in the performed code to determine when the iteration should end, and to exit the repeated processing. If you do not specify a statement to exit the repeat processing, processing continues indefinitely (in an infinite loop). Obviously several COBOL vendors and their customers have recognized that the lack of this feature is detrimental to desired coding practices. Shouldn t IBM Enterprise COBOL also support this feature as an extension. And shouldn t the COBOL standards committee (if one still exists!) provide this as a standard feature within the language? (Though now that there are at least three different syntaxes the question would be how do decide which syntax should be standard!) I write this document because IBM has already rejected my RFE requesting that Enterprise COBOL support some method of defining an unbounded loop, with their reasons being because it is not in the standard (*) and there are alternative methods of performing this facility. (*) Not in the standard hasn t stopped them from implementing many useful IBM extensions to COBOL, with one of the most recent being unbounded tables.

A Brief History of Loops in COBOL Genesis In the beginning there was the simple loop provided with the use of the GO TO statement. MAIN SECTION. PERFORM STOP RUN. PROCESS-MY-FILE SECTION. READ-MY-FILE. GO TO MY-FILE-AT-END. PROCESS-MY-RECORD. DISPLAY MY-RECORD. NEXT-RECORD. GO TO READ-MY-FILE. MY-FILE-AT-END. EXIT. Exodus Next there was the recommendation against the use of GO TO (in general), as well as some recommendation against use of procedure division sections. MAIN. PERFORM STOP RUN. PERFORM READ-MY-FILE. PERFORM UNTIL MY-FILE-AT-END PERFORM READ-MY-FILE READ-MY-FILE. SET MY-FILE-AT-END TO TRUE END-READ. PROCESS-MY-RECORD. DISPLAY MY-RECORD. So, what has been gained? And what has been lost?

The Good: - No use of GO TO. - No use of procedure division sections. - Continued use of separate paragraphs for discrete functions. The Bad: - Two different places where READ-MY-FILE is invoked. o Slightly confusing (though so prevalent you get used to it). o Bad for optimization. The optimizer either in-lines the READ logic in to two different places, or it does not inline it at all. - The addition of a variable to keep track of the at end condition. Leviticus (Yeah, my clever titling falls apart a bit here ) As an option to the above one could do the following instead. MAIN. PERFORM STOP RUN. PERFORM UNTIL MY-FILE-AT-END PERFORM READ-MY-FILE IF NOT MY-FILE-AT-END END-IF READ-MY-FILE. SET MY-FILE-AT-END TO TRUE END-READ. PROCESS-MY-RECORD. DISPLAY MY-RECORD. The Good: - Back to a single place where the record is read, allowing the optimizer to place it inline inside the loop. The Bad: - Continued need for the variable to keep track of the at end condition. - Redundant checking of the at end condition. The New Testament As of the 2002 COBOL standard there is now support for enhanced EXIT statements. This includes, which allows for early termination of a PERFORM loop. How might we make use of this for the above type of processing? MAIN. PERFORM

STOP RUN. PERFORM UNTIL MY-FILE-AT-END PERFORM READ-MY-FILE IF MY-FILE-AT-END ELSE END-IF READ-MY-FILE. SET MY-FILE-AT-END TO TRUE END-READ. PROCESS-MY-RECORD. DISPLAY MY-RECORD. Hmm, now that is interesting. We now exit the loop as soon as we know that - we want to terminate the loop - we don t want to do the process record logic prior to terminating the loop. But we still have: - Continued need for the variable to keep track of the at end condition. - Redundant checking of the at end condition. And in fact, there now will never be a case where the natural termination of the loop is reached, because we have explicitly terminated it with the so that any time the PERFORM loop itself checks for the at-end condition it will never be true. - So what is the point of even checking it there? Well, we have to check something! The COBOL standard does not allow an alternative. What if there were another way? MAIN. PERFORM STOP RUN. PERFORM UNTIL EXIT NOT END-READ The New Testament (Revised Edition)

PROCESS-MY-RECORD. DISPLAY MY-RECORD. Or a slight variation for the PROCESS-MY-FILE paragraph: PERFORM UNTIL EXIT END-READ The Good: - Both of these eliminate the need to set an at end variable only to check its value almost immediately afterward. - There is no need to perform the same paragraph in two different places. - No need for checking the truthness of a value that (at that point) can never be true. - It is still obvious (to me, anyway) what the condition is where the unbounded loop terminates. The Bad (?): - The read from file logic is no longer in its own paragraph, but is part of the inline perform. Since the processing of the record (PROCESS-MY-RECORD) is still out of line if feel having the inline READ in order to allow the to do the is a reasonable compromise. If you don t want to do that, you can always just use explicit FILE STATUS checking, as in the following example. PERFORM UNTIL EXIT PERFORM READ-MY-FILE IF MY-FILE-AT-END END-IF READ-MY-FILE. EVALUATE TRUE WHEN MY-FILE-SUCCESSFUL WHEN MY-FILE-AT-END CONTINUE WHEN OTHER PERFORM ERROR-WITH-MY-FILE END-EVALUATE. You could also use a DECLARATIVE section to handle unexpected I/O errors, which eliminates the need for the entire EVALUATE within READ-MY-FILE, which in turn makes READ-MY-FILE a single statement, so why have it in its on paragraph in the first place?

Of course there are other things loops are used for besides native COBOL I/O. In many of these cases there is a natural status code field (SQLCODE, IMS PCB status field, etc.) so there is not the issue with creating one only to be able to terminate the loop. Even in those cases I still think it makes sense to use an unbounded loop. PROCESS-MY-CURSOR. PERFORM UNTIL EXIT PERFORM FETCH-NEXT-RECORD IF SQLCODE = +100 END-IF FETCH-NEXT-RECORD. EXEC SQL FETCH MY-CURSOR INTO :MY-RECORD END-EXEC. EVALUATE SQLCODE WHEN ZERO WHEN 100 CONTINUE WHEN OTHER PERFORM ERROR-WITH-MY-CURSOR END-EVALUATE. (Not a Book in the Bible.) Reality So, the whole point to this is that neither the COBOL standard nor IBM Enterprise COBOL support the direct syntax for an unbounded loop. There are alternatives, are there not? Why don t you just use one of those? I will explain. The obvious alternative is to define a field that has a constant value, and then have your look check to make sure that the value is never some other value. 01 DUMMY-DONE-FLAG PIC X VALUE LOW-VALUES. 88 DONE VALUE HIGH-VALUES. PERFORM UNTIL DONE END-READ Does this work? Indeed, it does work, with several (important, at least to me) caveats.

You need to make sure you specify a VALUE for the field in its declaration. If you did not specify, for example, LOW-VALUES then there is the slight possibility that the field may coincidentally have a value of HIGH-VALUES already in it. In that case your loop would terminate immediately, having never performed any of the code inside it. Not good! OK, let s say you always remember to specify the VALUE clause. All is well, right? Not in my opinion. I have tested with COBOL 5.2 and several different values for the OPTIMIZE compile option. OPTIMIZE(0) Even though DONE is never true, the compiler still generates code to check to see if DUMMY-DONE-FLAG = HIGH-VALUES. So that s one instruction wasted. OPTIMIZE(1) and OPTIMIZE(2) Ah ha! The optimizer is doing its duty. It knows that DUMMY-DONE-FLAG can never be HIGH-VALUES, so it optimizes away the test. That s great! Well, except for the fact that this causes it does its duty so well that it eliminates the code in such a manner that it ends up causing a warning such as the following: IGYCB7300-W The code from lines ###.1 in program 'XXXX' can never be executed and was therefore discarded. So now a perfectly perfect (!) program results in warning and a Return code 4 condition!

Sidebar Although I am sure there are some obscure ones, I know of no major programming language other than COBOL that does not support unbounded loops. for (;;) {} while (1) {} C, C++, Java do forever; [ ] end; PL/I and REXX do loop; [ ] end; PL/I while true do [ ] Pascal, Delphi while 1: [ ] Python loop { } Ruby Perl 6 while true {} Groovy do [ ] loop Visual Basic while true {} Swift for { } Go LOOP [ ] END LOOP; Oracle PL/SQL and DB2 SQL PL WHILE 1=1 BEGIN [ ] END; Microsoft Transact-SQL Microsoft See the following link if you wish to know about more: https://www.rosettacode.org/wiki/loops/infinite. Interestingly, that page includes the supposed COBOL option of PERFORM UNTIL 1 <> 1, which is not valid COBOL at all in that at least one side of a comparison expression must not be a literal. (I guess it might be supported by some other COBOL implementation.) Not to mention that Enterprise COBOL does not even support <> as an abbreviation for not equal (though it is part of the 2014 COBOL standard). All of these, of course, have their own method of prematurely terminating a loop, just as COBOL now has (and CYCLE to iterate a loop).

Revelation All is not lost. While writing this document I thought of one more thing to try. And while I will not make any guarantees about it, it seems to do all of the following, at least with the version of Enterprise COBOL (5.2) that I am using: - Allows syntax that makes it obvious that this is an unbounded loop. - Allows the optimizer (both at OPT(1) and OPT(2)) to eliminate the code that checks for the termination of the loop. - It does so in a way that it does not cause the optimizer to issue any warning. At least in all the cases I have tested so far. The solution is to use the WITH TEST AFTER clause of the PERFORM, rather than the (default) WITH TEST BEFORE. (Hmm, just thought of PERFORM WITH NO TEST as another possible syntax for this loop construct!) For whatever reason (likely coincidence) this does all of the above, so let s go with it. I created a copybook named UNBOUND with the following lines: 01 PIC X VALUE LOW-VALUES. 88 UNBOUNDED VALUE HIGH-VALUES. REPLACE ==PERFORM UNBOUNDED== BY ==PERFORM WITH TEST AFTER UNTIL UNBOUNDED==. I chose to use UNBOUND/UNBOUNDED because it already exists as a contextsensitive keyword in Enterprise COBOL. That is, it is a keyword that can also be used as a user defined word. If you want to make it look more like Micro Focus COBOL s solution you can change UNBOUND and UNBOUNDED to FOREVER. Usage example: WORKING-STORAGE SECTION. COPY UNBOUND. PROCEDURE DIVISION. [...] PERFORM UNBOUNDED END-READ The REPLACE statement (assuming you don t have a REPLACE OFF before you get to it!) causes the final source code (as seen by the compiler) to be: PERFORM WITH TEST AFTER UNTIL UNBOUNDED END-READ

The optimizer still eliminates any checking of the unnamed filler that UNBOUNDED is a condition of to see if it s a value of high-values. But in this case it (apparently) leaves enough in place so that the optimizer hasn t eliminated every single instruction, and thus no superfluous warning is issued. So far now I think this is the best that can be done. In the end I still believe that IBM Enterprise COBOL, and the COBOL standard itself, should support at least one of these methods to represent an unbounded.