Repeat..Until

Description

The "repeat..until" loop has a similar purpose to the while loop of handling iteration for an indeterminate number of times. However it is organized so as to ask the loop termination expression at the end rather than the beginning and it asks in the opposite sense. A "while..do" loop continues while the condition is true. The "repeat..until" loop continues until the condition is false. The syntax of a "Repeat..Until" loop is:

repeat 
  <statement>;
until  <expression>;  

This is the only iterating construct which is guaranteed to execute its statement list at least one time. Execution passes by the repeat keyword and immediately performs the instructions in the repeat body. After doing these instructions a condition is evaluated. If the condition is true execution falls through the until keyword and continues past the construct. If the condition is false execution returns to the location indicated by "Repeat" and the loop is done again. For example:

repeat
  XAxis.MoveBy(PitchSetting);
until XAxis.ActualPosition >= 20;

This causes the XAxis to hop a small step repeatedly until the absolute position is greater than 20. The pitch setting can be adjusted. Although the math can be done to calculate the number of hops it is more direct to express the loop based on the desired result that the XAxis pass 20.

Repeat constructs are unusual in that they are the only construct which permits a group of statements, between the repeat and until keywords, without an enclosing begin..end construct although it is not a problem if the begin..end is present. The structure of the construct explicitly delimits the range of instructions so the compiler is able to distinguish the range without any additional help.

For the same reasons as explained for "while..do" constructs it is never appropriate to have an empty repeat construct. The following would be the minimum repeat body:

repeat
  yield;
until <condition>;

The decision between the while..do loop and repeat..until loop is influenced by whether at least one pass must be performed and by the readability of the termination condition. It is generally easier to understand positively expressed logic than negatively expressed logic. Consider a situation where an operation must be performed to get the information needed to judge whether something should continue:


This makes sense but assumes that a painting pass will succeed even if the paint level is low. The "while..do" case looks like this:


The "while..do" case requires more program lines because the preparation for the condition has to be done before the loop as well as within the loop. It also takes a bit of thinking to combine the "not" and the concept of low to get to the idea of "enough paint". There is also syntactical distance (more if there are many lines inside the loop) between the routine preparing the condition at the bottom and the while condition at the top where that information is needed. It usually helps understanding for cause and effect to be in close proximity.