Chapter 7: Conditional Logic -- Key Takeaways

Chapter Summary

Conditional logic is the foundation of any meaningful COBOL program. This chapter explored the three primary mechanisms COBOL provides for making decisions at runtime: the IF statement, the EVALUATE statement, and 88-level condition names. Together, these constructs allow programs to branch execution based on data values, user input, file status codes, and virtually any other testable condition that arises during processing.

The IF statement is the most fundamental conditional construct in COBOL, supporting simple tests, compound conditions using AND and OR, nested IF blocks, and the explicit scope terminator END-IF. While COBOL's IF statement resembles conditional constructs in other languages, its verbose English-like syntax and the legacy behavior of the period as a scope terminator introduce subtleties that demand careful attention. We examined how nested IF statements can quickly become difficult to read and how END-IF eliminates the ambiguity that plagued earlier COBOL programs relying on periods alone.

The EVALUATE statement, often compared to the switch or case statement in other languages, provides a cleaner alternative when a program must choose among multiple discrete values or ranges. Unlike a simple switch, EVALUATE supports testing multiple subjects simultaneously, matching ranges with THRU, and combining conditions in ways that make complex decision tables readable. Finally, 88-level condition names were introduced as a powerful COBOL-specific feature that attaches meaningful Boolean names to specific data values, dramatically improving code readability and maintainability throughout a program.

Key Concepts

  • The IF statement tests a condition and executes one or more statements when the condition is true; the optional ELSE clause handles the false case.
  • END-IF is the explicit scope terminator for IF statements and should always be used in modern COBOL instead of relying on periods to terminate scope.
  • Nested IF statements place one IF inside another's THEN or ELSE branch; deep nesting beyond three levels should be avoided for readability.
  • Compound conditions combine multiple tests using AND and OR; AND has higher precedence than OR, and parentheses should be used to make intent explicit.
  • The NOT operator negates a condition and can be applied to simple comparisons, compound conditions, or class tests.
  • Relational operators in COBOL include IS EQUAL TO (=), IS GREATER THAN (>), IS LESS THAN (<), IS NOT EQUAL TO, IS GREATER THAN OR EQUAL TO (>=), and IS LESS THAN OR EQUAL TO (<=).
  • Class conditions test the nature of data: IS NUMERIC, IS ALPHABETIC, IS ALPHABETIC-LOWER, IS ALPHABETIC-UPPER, and IS DBCS.
  • Sign conditions test whether a numeric item IS POSITIVE, IS NEGATIVE, or IS ZERO.
  • EVALUATE acts as COBOL's multi-way branch, evaluating one or more subjects against a series of WHEN clauses, executing the first matching branch.
  • EVALUATE TRUE is the most common form, allowing each WHEN clause to specify an independent condition, functioning as a cleaner alternative to nested IF.
  • WHEN OTHER in an EVALUATE block serves as the default case, executing when no other WHEN clause matches.
  • The 88-level condition name is defined under a data item and associates a meaningful name with one or more specific values of that item.
  • An 88-level item can specify a single value, multiple values separated by spaces, or a range of values using THRU.
  • SET statement can set an 88-level condition name to TRUE, which assigns the corresponding value to the parent data item.
  • CONTINUE is a no-operation statement used as a placeholder in IF or EVALUATE branches where no action is required.

Common Pitfalls

  • Dangling ELSE ambiguity: In legacy code without END-IF, a period terminates all open IF scopes, which can cause an ELSE to bind to the wrong IF. Always use END-IF to avoid this.
  • Operator precedence errors: Writing IF A = 1 OR 2 does not test whether A equals 1 or A equals 2. It tests whether A equals 1, or whether 2 is true (nonzero). The correct form is IF A = 1 OR A = 2.
  • Forgetting WHEN OTHER: Omitting the default case in an EVALUATE means that if no WHEN clause matches, execution simply falls through with no action, which may silently produce incorrect results.
  • Deeply nested IF blocks: Nesting IF statements more than three or four levels deep makes code nearly impossible to read and debug. Refactor using EVALUATE or PERFORM to separate paragraphs.
  • Comparing incompatible data types: Comparing a numeric field to an alphanumeric field can produce unexpected results or abends. Ensure both sides of a comparison are compatible types.
  • Misusing NOT with compound conditions: NOT (A = 1 AND B = 2) is not the same as NOT A = 1 AND NOT B = 2. Apply De Morgan's laws carefully or use parentheses to be explicit.
  • Omitting the subject in EVALUATE: Writing EVALUATE without a subject or without TRUE/FALSE leads to compilation errors. The subject expression is required.
  • Treating 88-levels as variables: An 88-level condition name is not a data item that holds a value. It is a Boolean alias for specific values of its parent item. You cannot MOVE a value to an 88-level.

Quick Reference

      * Simple IF/ELSE/END-IF
           IF WS-BALANCE IS NEGATIVE
               DISPLAY "Account overdrawn"
           ELSE
               DISPLAY "Account in good standing"
           END-IF

      * Compound condition with parentheses
           IF (WS-AGE >= 18 AND WS-AGE <= 65)
               OR WS-EXEMPT-FLAG = "Y"
               DISPLAY "Eligible"
           END-IF

      * EVALUATE with multiple WHEN clauses
           EVALUATE WS-GRADE
               WHEN "A"
                   MOVE "Excellent" TO WS-REMARK
               WHEN "B"
                   MOVE "Good" TO WS-REMARK
               WHEN "C" THRU "D"
                   MOVE "Needs Improvement" TO WS-REMARK
               WHEN OTHER
                   MOVE "Invalid Grade" TO WS-REMARK
           END-EVALUATE

      * EVALUATE TRUE for independent conditions
           EVALUATE TRUE
               WHEN WS-TEMPERATURE > 100
                   DISPLAY "Overheating"
               WHEN WS-TEMPERATURE < 32
                   DISPLAY "Freezing"
               WHEN OTHER
                   DISPLAY "Normal range"
           END-EVALUATE

      * 88-level condition names
       01  WS-ACCOUNT-STATUS     PIC X(01).
           88  ACCT-ACTIVE        VALUE "A".
           88  ACCT-CLOSED        VALUE "C".
           88  ACCT-SUSPENDED     VALUE "S".
           88  ACCT-VALID         VALUE "A" "C" "S".

      * Using SET with 88-level
           SET ACCT-ACTIVE TO TRUE
      * This assigns "A" to WS-ACCOUNT-STATUS

      * Using 88-level in IF
           IF ACCT-ACTIVE
               PERFORM PROCESS-ACTIVE-ACCOUNT
           END-IF

What's Next

Chapter 8 explores iteration through the PERFORM statement in all its forms. You will learn how to execute paragraphs and sections repeatedly using PERFORM TIMES, PERFORM UNTIL, and PERFORM VARYING, as well as inline PERFORM blocks. The chapter builds directly on the conditional logic covered here, since loop control conditions use the same relational and compound condition syntax introduced in this chapter. Mastering PERFORM is essential for processing files record by record, iterating through tables, and structuring COBOL programs into modular, maintainable units.