Книга: Practical Common Lisp

Equals-Then Iteration

Equals-Then Iteration

If none of the other for clauses supports exactly the form of variable stepping you need, you can take complete control over stepping with an equals-then clause. This clause is similar to the binding clauses in a DO loop but cast in a more Algolish syntax. The template is as follows:

(loop for var = initial-value-form [ then step-form ] ...)

As usual, var is the name of the variable to be stepped. Its initial value is obtained by evaluating initial-value-form once before the first iteration. In each subsequent iteration, step-form is evaluated, and its value becomes the new value of var. With no then part to the clause, the initial-value-form is reevaluated on each iteration to provide the new value. Note that this is different from a DO binding clause with no step form.

The step-form can refer to other loop variables, including variables created by other for clauses later in the loop. For instance:

(loop repeat 5
for x = 0 then y
for y = 1 then (+ x y)
collect y) ==> (1 2 4 8 16)

However, note that each for clause is evaluated separately in the order it appears. So in the previous loop, on the second iteration x is set to the value of y before y changes (in other words, 1). But y is then set to the sum of its old value (still 1) and the new value of x. If the order of the for clauses is reversed, the results change.

(loop repeat 5
for y = 1 then (+ x y)
for x = 0 then y
collect y) ==> (1 1 2 4 8)

Often, however, you'll want the step forms for multiple variables to be evaluated before any of the variables is given its new value (similar to how DO steps its variables). In that case, you can join multiple for clauses by replacing all but the first for with and. You saw this formulation already in the LOOP version of the Fibonacci computation in Chapter 7. Here's another variant, based on the two previous examples:

(loop repeat 5
for x = 0 then y
and y = 1 then (+ x y)
collect y) ==> (1 1 2 3 5)

Оглавление книги


Генерация: 1.319. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз