University of Virginia, Department of Computer Science
CS200: Computer Science, Spring 2002

Notes: Friday 1 February 2002
Schedule

Today's Task: Challenge Problem

Many programming languages provide an interation construct known as a for loop or do loop. Your task today is to define a procedure for that can be used in Scheme for what for loops are for and do loops do in other languages.

Fortran (1954) provided DO loops like this:

    SUM = 0
    DO 100 I = 1, N
       SUM = SUM + I
100 CONTINUE
This sums up the number from 1 to N. (The 100 after the DO is a label for the end of the loop, not how many times to iterate.)

Algol 60 (1960) introduced a for loop that is found in almost all common languages today (most of which evolved from Algol):

sum := 0
for i := 1 until N do
      sum := sum + i;
Below is an excerpt from The Java Language Specification by James Gosling, Bill Joy, Guy Steele and Gilad Bracha that describes the syntax and evaluation rule for the for statement in Java. Recall the BNF shortcut of using square brackets like [ Article ] to indicate that Article is optional. I've changed their grammar slightly to be consistent with the BNF notation we have seen in class. Just skim this for now, but I want you to see what the language specification really looks like.


14.13 The for Statement

The for statement executes some initialization code, then executes an Expression, a Statement, and some update code repeatedly until the value of the Expression is false.

ForStatement ::= for ( [ ForInit ] ; [ Expression ] ; [ ForUpdate ] ) Statement
ForInit ::= StatementExpressionList
ForUpdate ::= StatementExpressionList
StatementExpressionList ::= StatementExpression
StatementExpressionList ::= StatementExpressionList ,  StatementExpression
The Expression must have type boolean, or a compile-time error occurs.

14.13.1 Initialization of for statement

A for statement is executed by first executing the ForInit code:

If the ForInit code is a local variable declaration, it is executed as if it were a local variable declaration statement (§14.4) appearing in a block. The scope of a local variable declared in the ForInit part of a for statement (§14.13) includes all of the following:

If execution of the local variable declaration completes abruptly for any reason, the for statement completes abruptly for the same reason.

14.13.2 Iteration of for statement

Next, a for iteration step is performed, as follows:

If the value of the Expression is false the first time it is evaluated, then the Statement is not executed.


Your task is to define a procedure for that works like the Java for statement.

First, try defining a simple for that would allow us to write the sum function as:

(define (sum n)
  (for 1 n (lambda (sum i) (+ i sum)) 0))
The for procedure here has four parameters: The for procedure should apply the body function to the starting accumulation value and initial iteration value, and then use the resulting value as the next accumulation value.

You should also be able to use for to define fast-fibo. Here is the previous definition:

(define (fast-fibo n)
  (define (fibo-worker a b count)
    (if (= count 1)
        b
        (fibo-worker (+ a b) a (- count 1))))
  (fibo-worker 1 1 n))

With for, we can define fast-fibo as:

(define (fast-fibo n)
  (first 
   (for 
    1 n
    (lambda (accum i)      
      (list (+ (first accum) (second accum)) (first accum)))
    (list 0 1))))
Here, we use list to put two values in the accumulator (a and b in our previous definition), and first and second to extract those values in the body function.

If you have greater ambition, try to define a more general genfor procedure.

With your more general genfor, we should be able to define fast-fibo as:

(define (fast-fibo n)
  (first 
   (genfor 
    1                       ; initial iteration value
    (lambda (i) (<= i n))   ; test - if it evaluates to true when applied to current iteration value, keep going
    (lambda (i) (+ i 1))    ; increment function - how to get the next iteration value
    (lambda (accum i)       ; body function
      (list (+ (first accum) (second accum)) (first accum)))
    (list 0 1))))           ; initial accumulator value
You should only need about four lines to define for and genfor. Here's one implementation: for.ss


CS 655 University of Virginia
Department of Computer Science
CS 200: Computer Science
David Evans
evans@virginia.edu
Using these Materials