• No results found

The loop Command with a for-below Clause

In document Algorithmic Composition (Page 163-166)

Algorithmic Composition

Chapter 10 Functional Programming

12.1 The loop Command with a for-below Clause

Chapter 12 Iteration

Iteration in programming means repeated evaluation. In SAL, iteration is accomplished through loops. Loops evaluate a set of expressions over and over again. A loop should terminate after a specified number of repetitions or when a condition is met. SAL has several iterative forms, including a loop command with many variations. This chapter will show how to solve many of the same problems presented in Chapter 11, only using iteration instead of recursion, so the reader can easily compare recursive and iterative forms.

12.1 The

loop

Command with a

for-below

Clause

The most general iterative form in SAL is the loop command, which like a begin-end block organizes a set of commands, but unlike begin-end, the commands are repeated. Loop commands can in-clude clauses that create, initialize, and update local variables for each repetition. Loop commands can also include clauses that stop the repetition when certain conditions are met. For now, we will start with a simple form of loop, using a for clause to control the number of iterations.

The template for this simple form of loop is loop

for counter below count-expression commands

end

This loop is evaluated as follows: First, counter (a variable) is ini-tialized to zero, and count-expression is evaluated to obtain a number we will call limit. If counter is less than limit, commands (any num-ber of commands) are evaluated. Then counter is incremented by 1, and the loop repeats by again comparing counter to limit and evalu-ating commands again. When counter reaches or exceeds limit, the loop ends.

In Example 12.1.1, we use a loop to increment the counter count. As we enter the loop, the variable count starts counting at 0. We enter the body of the loop and print the value of count. count is then incremented (to 1). Because the new value of count is less than the count expression (4), the body of the loop is executed again. The it-erative process stops when count equals 4. The number of iterations

12.1 The loop Command with a for-below Clause 149 is given by the limit (4), and the values of the count range from 0 to limit - 1.

Example 12.1.1: A simple loop SAL> loop

for count below 4 display “loop”, count end

loop : COUNT = 0 loop : COUNT = 1 loop : COUNT = 2 loop : COUNT = 3

In Example 12.1.2, we define a function make-a-chromatic-lick using iteration rather than recursion. The purpose of the function is to create a list that generates a specified number of half steps from a starting key number. The begin statement first initializes the variable the-list (to nil). The notes we generate will be collected into the-list. The body of the begin contains a loop. The loop counter is index, and the count-expression is the number-of-notes we need to create.

When the list ends, we return the-list of notes. In the body of the loop, we use set with @= to cons the sum of starting-note and the index onto the-list. The list cons’ing process continues until the variable index is equal to the number-of-notes. The list is returned.

To help understand the iterative process, a display statement has been inserted into the loop body.

Example 12.1.2: make-a-chromatic-lick.sal

define function make-a-chromatic-lick(

starting-note, number-of-notes) begin

with the-list loop

for index below number-of-notes

set the-list @= starting-note + index display "make-a-lick", index, the-list end

return the-list end

When we call the function, we get the following results:

Example 12.1.3: output from make-a-chromatic-lick

SAL> print make-a-chromatic-lick(60, 6) make-a-lick : INDEX = 0 THE-LIST = (60) make-a-lick : INDEX = 1 THE-LIST = (61 60) make-a-lick : INDEX = 2 THE-LIST = (62 61 60) make-a-lick : INDEX = 3 THE-LIST = (63 62 61 60) make-a-lick : INDEX = 4 THE-LIST = (64 63 62 61 60) make-a-lick : INDEX = 5 the-list = (65 64 63 62 61 60)

{65 64 63 62 61 60}

Why does the list go from largest to smallest? Because we cons’ed the newly created element onto the front of the list (using

@=). If we want a list in ascending order, we could use the reverse function on the-list. Alternatively, we could use the &= operator to put the newly created elements at the end of the list. Note that extending lists at the end takes longer than cons’ing to the front because the computer must first find the end of the list. Because it is more efficient, cons’ing followed by a list reversal is a common coding pattern. (Unless lists are very long, you are unlikely to notice any difference in evaluation time.)

Example 12.1.4: make-a-chromatic-lick-2.sal, a revision

SAL> define function make-a-chromatic-lick(

starting-note, number-of-notes) begin

loop

with the-list

for index below number-of-notes set the-list @= starting-note + index display "make-a-lick", index, the-list finally return reverse(the-list) end

end

SAL> print make-a-chromatic-lick(60, 6) make-a-lick : index = 0 the-list = (60) make-a-lick : index = 1 the-list = (61 60) make-a-lick : index = 2 the-list = (62 61 60) make-a-lick : index = 3 the-list = (63 62 61 60) make-a-lick : index = 4 the-list = (64 63 62 61 60) make-a-lick : index = 5 the-list = (65 64 63 62 61 60)

{60 61 62 63 64 65}

In Example 12.1.2, we created the-list in a begin-end block so that it would still be in scope after the loop terminated, allowing us

In document Algorithmic Composition (Page 163-166)