Session 9
Loops

Purpose

Loops are meant to repeat a set of statements (a code block) several times with only minimal variation. For example, if you want to replay a sound object 3 times, you can just repeat the Play command in 3 consecutive lines:

Play Play Play

Or you can implement a loop like below (we'll deal with the syntactic details in a moment):

for i from 1 to 3 Play endfor

The loop head declares that the code block (consisting of one statement) in the loop is repeated 3 times. This is a somewhat silly example, since we gained nothing much. But consider the next example: You declare at the beginning of the script how often a sound object should be replayed (to be able to change the number of repetitions quickly):

numberOfRepetitions = 3

Now, you can't react to this declaration by repeating commands, because you don't know in advance what number is specified. With a loop, on the other hand, it's easy—we take the loop from above and use the variable numberOfRepetitions instead of a literal number as maximum number of repetitions:

numberOfRepetitions = 3 . . . for i from 1 to numberOfRepetitions Play endfor

Now, the loop head ensures that the code block is repeated as often as is declared in numberOfRepetitions.

Admittedly, these were pretty simple examples to demonstrate the purpose of loops. Then again, there isn't much more to say about loops, really. Loops are simple, yet very powerful constructs. Their only purpose is to implement a defined amount of repetitions for a code block. Most of the time, of course, you'll manage more complex loops than those above, however, it's not the loop construct itself which becomes more complex but the code block in between. There are no restrictions for the code block, i.e. it may be as complex as you wish, containing environment switches, input forms, conditionals, or even other loops (yes, loops may be nested).

Beware of infinite loops

The only aspect of the loop construct itself that needs some attention is the definition of the number of repetitions. A carelessly formulated stop condition may trigger an infinite loop, i.e. the code block is repeated over and over again, freezing Praat completely. To my knowledge, the only way to abort an infinite loop is to kill Praat (using the task manager of the operating system). Hopefully, you've saved the naughty script before you started the infinite loop, because killing Praat means losing all unsaved changes…

Praat offers three types of loops, the second and third being very similar. The first and most frequently used loop type is the for-loop. The for-loop fits best when the exact number of repetitions can be determined before the loop starts. For instance, if you want to process a bunch of files, you can establish the number of files before the loop starts and declare exactly the number of necessary repetitions. If the exact number of repetitions can't be established beforehand, a control condition must be declared. If you want the control condition to be tested before the loop starts, a while loop is most appropriate:

while the condition is true ... code block ... endwhile

If you want to pass through the loop at least once before testing the control condition, you'll choose a repeat loop:

repeat ... code block ... until the condition is true

In other words, with a while loop the condition is tested right at the beginning of the loop; if it is false from the start the code block is executed not even once. With repeat, the code block is executed at least once before the condition is tested for the first time.

Concerning stop conditions, the for-loop is the most uncomplicated loop type because declaring the exact number of repetitions beforehand is pretty specific: stop the loop when the number of repetitions is reached (nonetheless, it is possible to implement an infinite for-loop; see next section). while and repeat need more attention, because first you must invent a useful stop condition, and second you must assure that it is possible for the condition to change its status (from true to false or vice versa) while the loop is running.

Next: for-Loops