CS200: Computer Science, Spring 2002
Notes: Friday 1 February 2002
Today's Task: Challenge Problem
- 1 February: Read SICP, 1.3
- Saturday, 2 February, 11am: Bobby McFerrin A Capella Workshop (Old Cabell Hall, free)
- 4 February: Problem Set 2
- 6 February: Read SICP, 2.1 and 2.2 (through page 127). You don't need to read the example section 2.2.4, but probably don't want to miss the footnote on page 127 about William Barton Rogers, MIT's founder, who left UVa after too many students were rioting outside his pavillion.
- Before 18 March: GEB all of Part I
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 CONTINUEThis 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.
forstatement executes some initialization code, then executes an Expression, a Statement, and some update code repeatedly until the value of the Expression is
ForStatement ::= for ( [ ForInit ] ; [ Expression ] ; [ ForUpdate ] ) StatementThe Expression must have type
ForInit ::= StatementExpressionList
ForUpdate ::= StatementExpressionList
StatementExpressionList ::= StatementExpression
StatementExpressionList ::= StatementExpressionList , StatementExpression
boolean, or a compile-time error occurs.
14.13.1 Initialization ofA
forstatement 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
- If the ForInit code is a list of statement expressions (§14.8), the expressions are evaluated in sequence from left to right; their values, if any, are discarded. If evaluation of any expression completes abruptly for some reason, the
forstatement completes abruptly for the same reason; any ForInit statement expressions to the right of the one that completed abruptly are not evaluated.
forstatement (§14.13) includes all of the following:
If execution of the local variable declaration completes abruptly for any reason, the
- Its own initializer
- Any further declarators to the right in the ForInit part of the
- The Expression and ForUpdate parts of the
- The contained Statement
forstatement completes abruptly for the same reason.
14.13.2 Iteration of for statementNext, a
foriteration step is performed, as follows:
If the value of the Expression is
- If the Expression is present, it is evaluated, and if evaluation of the Expression completes abruptly, the
forstatement completes abruptly for the same reason. Otherwise, there is then a choice based on the presence or absence of the Expression and the resulting value if the Expression is present:
- If the Expression is not present, or it is present and the value resulting from its evaluation is
true, then the contained Statement is executed. Then there is a choice:
- If execution of the Statement completes normally, then the following two steps are performed in sequence:
- First, if the ForUpdate part is present, the expressions are evaluated in sequence from left to right; their values, if any, are discarded. If evaluation of any expression completes abruptly for some reason, the
forstatement completes abruptly for the same reason; any ForUpdate statement expressions to the right of the one that completed abruptly are not evaluated. If the ForUpdate part is not present, no action is taken.
- Second, another
foriteration step is performed.
- If execution of the Statement completes abruptly, see §14.13.3 below.
- If the Expression is present and the value resulting from its evaluation is
false, no further action is taken and the
forstatement completes normally.
falsethe 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.
- the initial iteration value, 1
- the final iteration value, n
- the body function a function that takes two parameters, the current accumulation value and the current iteration count, and evaluates to the next accumulation value
- the starting accumulation value, 0
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 valueYou should only need about four lines to define for and genfor. Here's one implementation: for.ss
University of Virginia
Department of Computer Science
CS 200: Computer Science
Using these Materials