Compound and abbreviated conditions
Real business rules combine several tests. COBOL joins conditions with
AND, OR and NOT, and lets you leave out repeated words so the code
reads like the spec.
IDENTIFICATION DIVISION.
PROGRAM-ID. COMPOUND.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-AGE PIC 99 VALUE 20.
01 WS-INCOME PIC 9(6) VALUE 18000.
01 WS-CODE PIC X VALUE "A".
PROCEDURE DIVISION.
IF WS-AGE >= 18 AND WS-AGE <= 65
DISPLAY "1 WORKING AGE"
END-IF
IF WS-AGE >= 18 AND <= 65
DISPLAY "2 SAME TEST, ABBREVIATED"
END-IF
IF WS-CODE = "A" OR "B" OR "C"
DISPLAY "3 CODE IS A, B OR C"
END-IF
IF WS-AGE < 25 OR WS-AGE > 60 AND WS-INCOME > 50000
DISPLAY "4 PRINTED: AND WENT FIRST"
END-IF
IF (WS-AGE < 25 OR WS-AGE > 60) AND WS-INCOME > 50000
DISPLAY "5 NOT PRINTED"
END-IF
IF WS-CODE NOT = "A" OR "B"
DISPLAY "6 ALWAYS TRUE - A BUG"
END-IF
IF WS-CODE NOT = "A" AND "B"
DISPLAY "7 NEITHER A NOR B"
ELSE
DISPLAY "7 CODE IS A OR B"
END-IF
STOP RUN.
Output:
1 WORKING AGE
2 SAME TEST, ABBREVIATED
3 CODE IS A, B OR C
4 PRINTED: AND WENT FIRST
6 ALWAYS TRUE - A BUG
7 CODE IS A OR B
Precedence: NOT, then AND, then OR
Line 4 surprises people. The writer meant "young or old, and high
income", but AND is evaluated before OR, so COBOL read it as
WS-AGE < 25 OR (WS-AGE > 60 AND WS-INCOME > 50000). The customer is 20,
so the whole thing is true. Line 5 adds parentheses and gets it right.
Rule of thumb: whenever a condition mixes AND and OR, add
parentheses. Even if you know the precedence, the next reader may not.
Abbreviated conditions
When consecutive tests share the same subject, you can omit it (line 2). When they also share the operator, you can omit that too (line 3):
| Written | Means |
|---|---|
A >= 18 AND <= 65 |
A >= 18 AND A <= 65 |
A = "X" OR "Y" |
A = "X" OR A = "Y" |
A NOT = "X" AND "Y" |
A NOT = "X" AND A NOT = "Y" |
The NOT trap
Line 6 is a genuine production bug pattern. "Code is not A or B" in
English means neither. But WS-CODE NOT = "A" OR "B" expands to
WS-CODE NOT = "A" OR WS-CODE NOT = "B", which is true for every
value. To say "neither", use AND (line 7) — or better, avoid negated
abbreviations altogether and use an 88:
01 WS-CODE PIC X.
88 CODE-A-OR-B VALUE "A" "B".
* ...
IF NOT CODE-A-OR-B
On the job
Business analysts write rules like "customers aged 18–70 who are
employed or have a score over 750". Translate them with explicit
parentheses, then test the boundaries: 17, 18, 70, 71. Boundary
mistakes (> versus >=) are among the most common defects found in
code review.
Your task
A loan pre-screening program reads four lines:
- applicant age (
WS-AGE) - annual income in whole euros (
WS-INCOME) - credit score (
WS-SCORE) - employment code (
WS-EMPLOYMENT):Ffull-time,Ppart-time,Sself-employed,Uunemployed
The applicant is eligible only if all of these hold:
- age is 18 to 70 inclusive
- employment code is
F,PorS - credit score is at least 600
- income is at least 30,000 or the credit score is at least 750
Display ELIGIBLE or NOT ELIGIBLE. Write it as one IF with a
compound condition, and use abbreviated conditions for the age range and
the employment codes.