Title: Iteration and Recursion
1Iteration and Recursion
Programming Language Principles Lecture 21
- Prepared by
- Manuel E. Bermúdez, Ph.D.
- Associate Professor
- University of Florida
2Iteration
- Execute a block multiple times for its side
effects. - Enumeration controlled loops
- Execute a block for every value in a finite set.
- Fortran
- do 10 i1,10,2
- ...
- 10 continue
-
3Classic Problems in Fortran
- 'do' as prefix of assignment
- do7ij34,20 do loop
- do7ij34 assignment
- 'do7i' is a valid identifier.
- 'do' not a reserved word in
Fortran. - Need to look ahead arbitrary
distance, to the 'comma'.
4Classic Problems in Fortran (contd)
- Loop body can change the loop index
- do 10 i2,20
- ii-1
- 10 continue infinite loop
- Goto's can jump into the middle
- of a loop.
- So what's the value of the index,
- in that case ??
5Classic Problems in Fortran (contd)
- If goto branches out of loop, value of i is last
assigned. If loop terminates normally, value of
i is implementation-defined. - Last increment of i can cause overflow negative
value ??? -
- Fortran loop is bottom-tested loop body will
execute at least once.
6Pascal
- (and Modula, and most languages with enumeration
controlled loops) - for i first to last by step do
- begin
- ...
- end
7Pascal (contd)
- Questions
- Can i, first or last be modified in the loop?
- If so, what is the effect?
- What if first gt last?
- What 's the value of i when done?
- Can one jump from outside, into the loop?
- What if first has a side effect on i, or on last,
or vice-versa?
8Pascal (contd)
- Most languages prohibit modifying the loop index.
- Very expensive to check at compile time. Need to
check for - Assignments to i
- Nested loops that use i.
- Passing i to a procedure by reference.
- Reading i.
9Pascal (contd)
- What does this Pascal for statement do?
- i 7
- for i i1 to i8 do
- begin
- ...
- end
-
- What if instead of i1, we had f(i), where f
takes i as a reference parameter ?
10Modern For Loops Are Top-Tested
11Modern For Loops Are Top-Tested (contd)
- Works only for positive steps.
- In Pascal, for i 10 down to 1 do ...
- In Ada, for i in reverse 1..10 do ...
- In Modula, FOR i 10 to 1 STEP -1
compile-time constant
12Modern For Loops Are Top-Tested (contd)
- In Fortran
- No "backward" syntax,
- Compile-time constant steps not required.
- Can use an "iteration count
13Modern For Loops Are Top-Tested (contd)
- In C, C, Java, it's simple. No loop index.
- for (e1 e2 e3) body
-
- Code is
- e1
- L2 if not e2 goto L1
- body
- e3 lt--- any 'continue' branches
here - goto L2
- L1 ...
14Modern For Loops Are Top-Tested (contd)
- NOT equivalent to
- e1
- while (e2)
- body / if this contains a 'continue', /
- e3 / e3 is not executed /
15Modern For Loops Are Top-Tested (contd)
- In C, programmer's responsibility
- effect of overflow.
- index, other variables, can be modified inside
loop. - e1, e2, e3 are all optional. If e2 is missing,
it's considered to be a 1 (true).
16Access to the Index Outside the Loop
- Fortran IV, Pascal, leave the loop index
undefined. - Fortran 77, Algol 60, leave the "last value
assigned". - In Pascal,
- var c 'a' .. 'z'
- for c 'a' to 'z' do
- begin
- ...
- end
- ( what's the value of c ? )
17Access to the Index Outside the Loop (contd)
- Compiler forced to generate slower code
- Two branches in each iteration
18Access to the Index Outside the Loop (contd)
- Several languages (Algol W, Algol 68, Ada,
Modula-3, new ISO C) - loop header declares loop index.
- loop index's type is inferred from loop bounds.
- not visible outside the loop.
19Combination Loops
- Algol 60 allows a 'for-list' of enumerated
values/ranges. - Syntax
- Stmt 'for' id ' Enumerator list ',' 'do'
Stmt
Enumerator Expr Expr 'step' Expr
'until' Expr Expr while Condition
20Combination Loops (contd)
- Examples (all three are equivalent)
- for i 1, 3, 5, 9 do ...
- for i 1 step 2 until 10 do ...
- for i 1, i 2 while i lt 10 do ...
21Iterators
- An iterator allows examination of the elements in
a data structure, one at a time. - Various kinds of iterators available in Clu, Icon
(see textbook). - Java has a built-in iterator class.
22Iterator Methods in Java
- Iterator ix x.iterator()
- Constructs and initializes an iterator for the
elements of x. - ix is the new iterator.
- The class for x must define the iterator() method.
23Iterator Methods in Java (contd)
- ix.hasNext()
- Returns true iff x has a next element.
- ix.next()
- Return next element
- Throws NoSuchElementException if there is no next
element.
24Iterator Methods in Java (contd)
- ix.remove()
- Removes last element returned by ix.next().
- Throws UnsupportedMethodEXception if method not
implemented. - Throws IllegalStateException if ix.next() not yet
called or did not return an element.
25 Using the Iterator
- Iterator ix x.iterator()
- while (ix.hasNext())
- examine(ix.next())
- Much better than
- for (int i0 iltx.size() i)
- examine (x.get(i))
26Advantages of Iterators
- More abstraction. Object class "knows" how to
iterate. - Often possible to implement next() more
efficiently than get(). Example linked list. - Data structures often have no get-by-index method.
27"Faking" an Iterator in C
- Using a "fake" iterator in C
- C code for the binary tree pre-order traversal
iterator (see textbook).
28Logically Controlled Loops
- Semantically less complex (fewer subtleties).
- Execute statement (or block) until a condition
becomes true/false (while) - Variations (syntactic sugar of each other)
29Logically Controlled Loops (contd)
- while condition do block (Pascal, Modula)
- while (condition) block (C, C, Java)
- for i irrelevant_expression
- while condition do statement (Algol)
- 10 if negated-condition goto 20
- block
- goto 10
- 20 (Fortran)
30Logically Controlled Loops (contd)
- Post-tested loops (execute at least once)
- repeat statements until condition (Pascal)
- do statement while condition (C, C,
Java)
31Mid-Tested Loops (Quit Anytime)
- loop
- statement_list
- when condition exit
- statement_list
- when condition exit
- ...
- end (Modula-1)
- 'exit' is built in, along with 'when', so exiting
from a nested construct is impossible.
32Modula-2
- Favored a simple EXIT Statement
-
- LOOP
- line ReadLine
- IF AllBlanks(line) THEN EXIT END
- ConsumeLine(line)
- END
- EXIT statements are only allowed to appear inside
LOOPs. - Difficult to enforce.
33Modula-3
- EXIT can abort a WHILE, REPEAT, or FOR loop.
- C
- for ()
- line read_line(stdin)
- if (all_blanks(line)) break
- consume_line (line)
-
34C Loops
- M. Scott says "for some reason, for() has
traditionally been favored over the equivalent
while (1)". - The actual original reason was efficiency, not
style - older compilers would actually test the 1 each
time around the while loop. - With today's compilers, it should make no
difference.
35Mid-Tested Loops (contd)
- Euclid, Ada
- loop
- ...
- exit when condition
- end loop
36Mid-Tested Loops (contd)
- Java
- loops can be labeled,
- 'break' statement has optional label.
- outer while (true)
- get_line(line)
- for (i1 iltlength i)
- if linei'' break outer
- consume_line(line)
-
-
37Recursion
- Any iterative formulation can be expressed as
recursion, and vice versa. They are equally
powerful. - Some functional languages do not allow iteration.
- Iteration often more efficiently implemented.
38Recursion (contd)
- Optimizing compilers for functional languages
usually generate very good code. - The use of iteration/recursion is mostly a matter
of ease of use - Iteration more efficient than recursion ?
- Naive implementations are.
39Recursion (contd)
- For some problems, iteration seems natural.
- for (ilow ilthigh i)
- total f(i)
- For other problems, recursion seems more natural
- let gcd a b a eq b -gt a
- a lt b -gt gcd a (b-a)
- gcd (a-b) b
40Recursion (contd)
- In C,
- int gcd (int a, int b)
- if (ab) return a
- else if (a gt b) return gcd(a-b,b)
- else return gcd(a, b-a)
-
- In both cases, the choice could go the
- other way.
41Recursion (contd)
- Summation in C, recursive
- typedef int (int_func) int
- int summation (int_func f, int low, int high)
- if (low high) return f (low)
- else return f(low) summation(f,
low1,high) -
42Recursion (contd)
- GCD in C, non-recursive
- int gcd(int a,int b)
- while(a!b)
- if (a gt b) a a - b
- else b b - a
- return a
-
43Tail-Recursion
- Additional computation never follows a recursive
call. (nothing done as recursion unwinds). - No need to allocate stack space dynamically we
can reuse previous space. - Continuation-passing style
- can always avoid doing work after recursive call
by passing that work into the recursive call, a
continuation.
44Tail-Recursion (contd)
- Example (RPAL)
- let rec f n n eq 1 -gt 1 n f (n-1)
- in f 3
- let f n rf n 1 where
- rec rf n r n eq 1 -gt r rf (n-1) (nr)
- in f 3
-
45Tail-Recursion in Scheme
46Tail-Recursion (contd)
- Recursion does not lead to algorithmically
inferior programs. - Instead, the style of programming just changes
(paradigmatically).
47Fibonacci tail-recursion (Scheme vs. C)
48Applicative and Normal-Order Evaluation
- Called Normal Order and PL Order in RPAL.
- Normal order (passing unevaluated parameters) is
used for macros in C.
49Applicative and Normal-Order Evaluation (contd)
- Example
- define DIVIDES(n,a) (!((n) (a)))
- / true iff n a is zero /
- Preprocessor replaces
-
- DIVIDES (x,yz)
- (textually!, no evaluation) with
- (!((x) (yz)))
-
50Applicative and Normal-Order Evaluation (contd)
- Parentheses (n), (a) are crucial. Without them,
- DIVIDES (x,yz)
- is replaced with
-
- (!(x yz))
- which is equivalent to
-
- (!((x y)z))
51Applicative and Normal-Order Evaluation (contd)
- Macros are problematic
- define MAX(a,b) ((a) gt (b) ? (a) (b)
- MAX(x, y)
- will increment either x (or y) TWICE !
52Applicative and Normal-Order Evaluation (contd)
- Advantage of macros
- Efficient ! No function call overhead.
- In C, 'inline' tells compiler to try to convert
function call to a macro. - Algol 60 uses normal order, with PL order also
available.
53Non-Determinacy
- Construct in which the choice between
alternatives is deliberately unspecified. - Example
- n n in C
- (order of evaluation unspecified)
54Non-Determinacy (contd)
- Sometimes makes it easier to reason about
program. - Mostly a set of guarded commands from which any
guard that is true can be selected.
55Non-Determinacy (contd)
- Example (SR, adopted Dykstra's guarded command)
- if a gt b -gt max a
- b gt a -gt max b
- fi
- Nondeterministic choice made among guards that
evaluate to true.
56Non-Determinacy (contd)
- Also used for loops
- do a gt b -gt a a - b
- b gt a -gt b b - a
- od
- gcd a
- Loop quits when no guard is true.
- We wish to ensure fairness each candidate
equally likely to execute. -
57Iteration and Recursion
Programming Language Principles Lecture 21
- Prepared by
- Manuel E. Bermúdez, Ph.D.
- Associate Professor
- University of Florida