Some repetition is naturally check-first: keep reading while more records remain, keep processing while a queue is not empty, keep retrying while a resource stays unavailable. In every one of these cases, the correct behavior on the very first pass depends on a condition that must be checked before any work happens at all — including the possibility that the work should not happen even once. RPGLE’s DOW operation code expresses exactly that kind of repetition: it repeats a controlled group while an expression is true, checking that expression before the body ever runs.12
This tutorial focuses on that single, pre-test form. It assumes you already understand counted DO repetition and keeps the contrast with post-test DOU brief and conceptual, since that timing difference was already introduced when DOU was covered.
Quick Summary
- Write a pre-test group as
dow indicator-expression; ... enddo;.1 - The expression is evaluated before the body executes, both on entry and again at
ENDDO. Repetition continues while the expression is true and stops once it becomes false.1 - Because the check happens before the body, a
DOWgroup can execute zero times if the expression is already false the first time it is reached.1 ENDDOmarks the end of the group and is where RPG returns control so the condition can be re-evaluated before another pass.2- Use
DOWwhen the business rule is “check first, then work only if the check passes” — not when the work must always happen at least once. - The loop can only stop if something the body does changes the outcome of the condition. A condition that never changes and starts true produces an infinite loop.
- Trace the very first check by hand, especially when the condition might already be false before entry, to confirm zero iterations is the intended outcome.
Reader Prerequisites
You should already be comfortable with counted repetition from RPGLE DO Loops Explained (ARTICLE-068), including the index, limit, body, and ENDDO vocabulary. This tutorial reuses that vocabulary and replaces the numeric range with a condition checked before every pass, including the first.
The wider learning sequence is collected in RPGLE for Beginners: A Practical IBM i Learning Path (ARTICLE-046).
Learning Outcomes
After reading, you should be able to:
- State what
DOWmeans and when its condition is evaluated relative to the body. - Explain why a
DOWgroup can execute zero times. - Trace a counter-based
DOWloop and a state/sentinel-drivenDOWloop, including the boundary where the condition starts false. - Recognize the infinite-loop risk created by a condition whose state the body never updates.
- Choose
DOWonly when “check first, then work only if true” actually matches the business rule.
Why Pre-Test Repetition Exists
Some tasks are naturally check-first: process records while more remain, keep retrying while a connection is still down, keep looping while a balance is positive. For that family, the check is not an afterthought performed once work has already started — it is the gate that decides whether work should start at all. If the gate is already closed the first time the program reaches it, the correct behavior is to do nothing and move on.
DOW matches that check-first shape directly. The body is guarded by an entry test the same way it is guarded on every later pass; RPG asks “is this still true” before it will run the body even once.1 This makes DOW the natural fit for read-and-process loops, availability checks, and any task where “there might be nothing to do” is a normal, expected outcome rather than an edge case.

Anatomy of an RPGLE DOW Loop
Here is the smallest complete pre-test example:
dcl-s attemptLimit int(10) inz(5);
dcl-s attemptCount int(10) inz(0);
dow attemptCount < attemptLimit;
attemptCount += 1;
dsply ('Attempt ' + %char(attemptCount));
enddo;
The parts have distinct responsibilities:
| Part | Example | Responsibility |
|---|---|---|
| While-condition | attemptCount < attemptLimit | Indicator-valued expression evaluated before the body, on every pass including the first |
| Body | attemptCount += 1; dsply ... | Work performed only when the condition is currently true, including the state the condition depends on |
| Terminator | enddo; | Closes the group; RPG returns here so the condition can be re-evaluated before another pass |
IBM documents DOW as controlling a group of operations performed only while the expression in the condition is true, with ENDDO as its matching end operation.12 The variable names above and the recommendation to keep the condition’s state visible in the body are teaching and readability guidance, not compiler requirements.

How the Loop Progresses
Trace basic-dow-loop.rpgle one state at a time, starting with attemptCount at 0 and attemptLimit at 5:
| Moment | attemptCount | What happens |
|---|---|---|
Enter DOW | 0 | Check 0 < 5 — true; proceed to the body |
| First body execution | 0 → 1 | Increment, then display “Attempt 1” |
Return to DOW check | 1 | 1 < 5 is true; repeat |
| … | … | Passes 2 through 4 follow the same pattern |
| Fifth body execution | 4 → 5 | Increment, then display “Attempt 5” |
Return to DOW check | 5 | 5 < 5 is false; continue after the group |
The critical detail is the very first row: RPG checks attemptCount < attemptLimit before the body ever runs, exactly the same way it checks on every later pass. There is no special “first time” exemption — the condition sits at the top of the group, not at ENDDO, so it always governs entry.12 This is conceptual source-level behavior; the diagram and trace do not claim anything about compiler internals or generated machine instructions.
Counter-Based DOW Example
basic-dow-loop.rpgle is the example traced above. It stops as soon as attemptCount reaches attemptLimit, giving exactly five displayed attempts. The pattern — initialize a counter, check before working, do work, advance the counter — looks similar to counted DO, but the stopping question is phrased as a condition rather than a range, and the check controls entry to the work rather than following it.
The Pre-Test Boundary: Zero Iterations
The most important boundary case for DOW is not an off-by-one count; it is what happens when the while-condition is already false before the loop is ever entered. dow-zero-iteration-boundary.rpgle makes this visible:
dcl-s remainingItems int(10) inz(0);
dcl-s iterationsRun int(10) inz(0);
dow remainingItems > 0;
iterationsRun += 1;
remainingItems -= 1;
dsply ('Iteration ' + %char(iterationsRun) + ' remaining ' + %char(remainingItems));
enddo;
dsply ('Total iterations ' + %char(iterationsRun));
remainingItems starts at 0, which already fails remainingItems > 0. A reader who expects a loop to always do something at least once might predict one iteration by habit. The intended, documentation-based result is iterationsRun = 0: the body never runs, because DOW tests the condition before the first pass and finds it already false.1 Confirming this boundary by hand, with a deliberately “nothing to do” starting value, is the fastest way to catch a mistaken assumption carried over from a post-test loop.
State/Sentinel-Driven DOW Example
Not every DOW condition is a simple counter comparison. readable-dow-processing.rpgle models a small connection-retry sequence where the continue-question combines a not-yet-successful flag with a maximum-attempts safeguard, both checked before every attempt:
dow not connectionEstablished and connectionAttemptNumber < maxConnectionAttempts;
connectionAttemptNumber += 1;
connectionEstablished = (connectionAttemptNumber = maxConnectionAttempts);
dsply ('Connection attempt ' + %char(connectionAttemptNumber));
enddo;
With maxConnectionAttempts set to 3, the loop tries at most three times and stops as soon as connectionEstablished turns on. If connectionEstablished had already been *on before the loop started, the loop would run zero times — there would be nothing left to do. This is a common shape for real retry logic — a state flag for “do we still need to try” combined with a count-based safeguard so the loop cannot run forever even if the flag never turns on. Both variables are updated inside the body, and the updated values are what the next DOW check reads before allowing another pass.
All three members in this tutorial are documentation-reviewed; not compiled or run on IBM i in this workspace. Their traced values follow from initialized values and documented DOW/ENDDO behavior, not captured runtime output.
Common Mistakes
Forgetting to update the state the condition depends on. If nothing in the body changes the value(s) the DOW condition reads, and the condition starts true, it can never become false, and the loop repeats forever. This is the single most consequential DOW mistake — always identify which variable(s) the while-condition reads and confirm the body writes to at least one of them on every pass.
Assuming DOW always runs at least once. As dow-zero-iteration-boundary.rpgle shows, the body can execute zero times when the condition is already false on entry. Code that depends on the body running once unconditionally belongs in a post-test structure, not DOW.
Using DOW when a numeric range is already known. If the real stopping rule is “repeat exactly N times,” counted DO states that directly; reaching for a condition to express a known count adds an extra place for the count to drift.
Relying on a single flag with no safeguard. A pure success flag with no maximum-attempts guard can loop forever if success never arrives for a legitimate reason, such as a permanently unreachable resource. Combining a state flag with a bounded count, as in the retry example, keeps the loop safely terminating.
Hiding the condition’s state far from the loop. If the variables read by the DOW condition are updated deep inside a long body, a reader cannot quickly confirm the loop terminates or predict whether the next pass will even happen.
Confusing an attempt count with a success count. connectionAttemptNumber counts tries, not successes. Naming each state variable for exactly what it counts avoids reusing one variable for two different questions.
Readability Guidance
The following are editorial recommendations, not compiler requirements:
- Name every variable the while-condition reads for what it represents (
attemptCount,remainingItems,connectionEstablished) rather than reusing a generic flag across unrelated loops. - Keep the statement that updates the condition’s state close to the top or bottom of the body, not buried in unrelated work.
- When a condition combines a state flag with a safeguard count, write both in one line so a reader sees the full continue-rule at a glance.
- Comment the intended maximum number of passes when a safeguard count exists, so a future reader knows it is a safety limit, not an arbitrary number.
- Treat a zero-iteration outcome as a normal, expected result worth a brief trace, not a bug to explain away.
IBM defines what DOW and ENDDO do.12 These naming and layout choices are maintainability guidance from this tutorial.
Choosing the Right Loop Structure
Choose a structure by asking what governs completion and when the check belongs:
| Question | Appropriate direction |
|---|---|
| “Repeat for these numeric positions” | Counted DO — ARTICLE-068 |
| “Run at least once, then stop when a condition becomes true” | DOU — ARTICLE-069 |
| “Run only while a condition is true, and skip entirely if it starts false” | DOW — this article |
DOW differs from DOU in exactly one respect that matters here: DOW tests its condition before the body, so it can skip the body entirely on the first pass. DOU cannot skip the first pass, because its condition lives at ENDDO, after the body.6 Detailed LEAVE, ITER, nested loops, arrays, and file-reading loops remain outside this tutorial’s scope.
FAQ
Does a DOW loop check its condition before the first pass, or can it run zero times?
Yes to both. The condition is evaluated before the body on every pass, including the first, so the body can execute zero times if the condition is already false when the loop is reached.1
What happens if the condition’s state never changes and starts true?
The condition never becomes false, and the loop repeats indefinitely. Confirm that some statement in the body writes to every variable the while-condition reads.
Is DOW the right choice for reading records until end of file?
Often yes, if “check for more records, then read only if some remain” matches your actual sequence. Verify the intended timing before choosing DOW over a post-test structure, since some read patterns are naturally do-first instead.
Can the while-condition combine more than one thing, like a flag and a count?
Yes. readable-dow-processing.rpgle combines a not-yet-successful flag with a maximum-attempts count using and, which is ordinary indicator-expression logic, not a special DOW feature.1
Were these examples tested on IBM i?
No. They are documentation-reviewed against IBM i 7.5 and 7.4 references, but were not compiled or run on IBM i in this workspace.
Key Takeaways
- A pre-test RPGLE
DOWgroup repeats a body while an expression is true, checked before the body runs, both on entry and again atENDDO.12 - The body can execute zero times if the condition is already false the first time it is reached.
- The loop can only terminate if the body updates the state the condition depends on.
- Combine a state flag with a bounded safeguard count when “success” alone might never arrive.
- Choose
DOfor known numeric ranges andDOUwhen the work must always happen at least once before any check. - Treat descriptive naming, visible state updates, and hand-tracing as editorial guidance rather than IBM compiler requirements.
Continue Your Learning
- Pillar: RPGLE for Beginners: A Practical IBM i Learning Path (ARTICLE-046)
- Prerequisite: RPGLE DO Loops Explained (ARTICLE-068)
- Related: RPGLE DOU Loops Explained (ARTICLE-069)
- Current: RPGLE DOW Loops Explained (ARTICLE-070)
- Recommended next: RPGLE LEAVE, ITER, and Loop Control (ARTICLE-071)
ARTICLE-071 and ARTICLE-072 are named from the canonical registry but remain unlinked until publishable repository routes exist.
IBM Evidence Used
The IBM i 7.5 DOW reference is the primary source for pre-test timing, the zero-iteration possibility, and condition evaluation before the body.1 The matching ENDDO reference supports how the group closes and returns control for re-evaluation.2 IBM’s structured-programming overview supplies the broader grouping context shared with counted DO and DOU.3
The IBM i 7.4 DOW and ENDDO topics were cross-checked for the same operation model.45 No publication date is assigned to any IBM Docs page. Recommendations about naming, state-update discipline, safeguard counts, and hand-tracing are editorial guidance; they are not represented as IBM compiler rules.
References
IBM, DOW (Do While), IBM i 7.5, accessed 2026-09-13. ↩↩↩↩↩↩↩↩↩↩↩↩↩
IBM, ENDDO (End Do), IBM i 7.5, accessed 2026-09-13. ↩↩↩↩↩↩↩
IBM, Structured Programming Operations, IBM i 7.5, accessed 2026-09-13. ↩
IBM, DOW (Do While), IBM i 7.4, accessed 2026-09-13. ↩
IBM, ENDDO (End Do), IBM i 7.4, accessed 2026-09-13. ↩
IBM, DOU (Do Until), IBM i 7.5, accessed 2026-09-13. ↩
References
- DOW (Do While) — IBM
- ENDDO (End Do) — IBM
- DOU (Do Until) — IBM
- Structured Programming Operations — IBM
- DOW (Do While) — IBM
- ENDDO (End Do) — IBM