1 / 57

Iteration and Recursion

Iteration and Recursion . Programming Language Principles Lecture 21. Prepared by Manuel E. Bermúdez, Ph.D. Associate Professor University of Florida. Iteration. Execute a block multiple times for its side effects. Enumeration controlled loops:

pepin
Télécharger la présentation

Iteration and Recursion

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Iteration and Recursion Programming Language Principles Lecture 21 Prepared by Manuel E. Bermúdez, Ph.D. Associate Professor University of Florida

  2. Iteration • 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 i=1,10,2 ... 10 continue :

  3. Classic Problems in Fortran • 'do' as prefix of assignment: do7i=j+3*4,20 do loop do7i=j+3+4 assignment 'do7i' is a valid identifier. 'do' not a reserved word in Fortran. Need to look ahead arbitrary distance, to the 'comma'.

  4. Classic Problems in Fortran (cont’d) • Loop body can change the loop index: do 10 i=2,20 i=i-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 ??

  5. Classic Problems in Fortran (cont’d) • 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.

  6. Pascal • (and Modula, and most languages with enumeration controlled loops): for i := first to last by step do begin ... end;

  7. Pascal (cont’d) • Questions: • Can i, first or last be modified in the loop? • If so, what is the effect? • What if first > 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?

  8. Pascal (cont’d) • 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.

  9. Pascal (cont’d) • What does this Pascal for statement do? i := 7; for i := i+1 to i+8 do begin ... end; • What if instead of i+1, we had f(i), where f takes i as a reference parameter ?

  10. Modern For Loops Are Top-Tested

  11. Modern For Loops Are Top-Tested (cont’d) • 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

  12. Modern For Loops Are Top-Tested (cont’d) • In Fortran • No "backward" syntax, • Compile-time constant steps not required. • Can use an "iteration count“

  13. Modern For Loops Are Top-Tested (cont’d) • 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; <--- any 'continue' branches here goto L2 L1: ...

  14. Modern For Loops Are Top-Tested (cont’d) • NOT equivalent to: e1; while (e2) { body; /* if this contains a 'continue', */ e3; /* e3 is not executed */ }

  15. Modern For Loops Are Top-Tested (cont’d) • 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).

  16. Access 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 ? *)

  17. Access to the Index Outside the Loop (cont’d) • Compiler forced to generate slower code • Two branches in each iteration

  18. Access to the Index Outside the Loop (cont’d) • 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.

  19. Combination 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

  20. Combination Loops (cont’d) • 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 < 10 do ...

  21. Iterators • 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.

  22. Iterator 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.

  23. Iterator Methods in Java (cont’d) ix.hasNext() • Returns true iff x has a next element. ix.next() • Return next element; • Throws NoSuchElementException if there is no next element.

  24. Iterator Methods in Java (cont’d) 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 i=0; i<x.size(); i++) examine (x.get(i));

  26. Advantages 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).

  28. Logically Controlled Loops • Semantically less complex (fewer subtleties). • Execute statement (or block) until a condition becomes true/false (while) • Variations (syntactic sugar of each other):

  29. Logically Controlled Loops (cont’d) 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)

  30. Logically Controlled Loops (cont’d) • Post-tested loops (execute at least once): repeat statements until condition (Pascal) do statement while condition (C, C++, Java)

  31. Mid-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.

  32. Modula-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.

  33. Modula-3 • EXIT can abort a WHILE, REPEAT, or FOR loop. C: for (;;) { line = read_line(stdin); if (all_blanks(line)) break; consume_line (line); }

  34. C 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.

  35. Mid-Tested Loops (cont’d): • Euclid, Ada: loop ... exit when condition; end loop;

  36. Mid-Tested Loops (cont’d): • Java: • loops can be labeled, • 'break' statement has optional label. outer: while (true) { get_line(line); for (i=1; i<=length; i++) if line[i]='#' break outer; consume_line(line); }

  37. Recursion • 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.

  38. Recursion (cont’d) • 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.

  39. Recursion (cont’d) • For some problems, iteration seems natural. for (i=low; i<=high; i++) total += f(i); • For other problems, recursion seems more natural: let gcd a b = a eq b -> a | a < b -> gcd a (b-a) | gcd (a-b) b

  40. Recursion (cont’d) • In C, int gcd (int a, int b) { if (a==b) return a; else if (a > b) return gcd(a-b,b); else return gcd(a, b-a); } • In both cases, the choice could go the other way.

  41. Recursion (cont’d) • 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, low+1,high); }

  42. Recursion (cont’d) • GCD in C, non-recursive: int gcd(int a,int b) { while(a!=b) if (a > b) a = a - b; else b = b - a; return a; }

  43. Tail-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.

  44. Tail-Recursion (cont’d) • Example (RPAL): let rec f n = n eq 1 -> 1 | n * f (n-1) in f 3 let f n = rf n 1 where rec rf n r = n eq 1 -> r | rf (n-1) (n*r) in f 3

  45. Tail-Recursion in Scheme

  46. Tail-Recursion (cont’d) • Recursion does not lead to algorithmically inferior programs. • Instead, the style of programming just changes (paradigmatically).

  47. Fibonacci tail-recursion (Scheme vs. C)

  48. Applicative and Normal-Order Evaluation • Called Normal Order and PL Order in RPAL. • Normal order (passing unevaluated parameters) is used for macros in C.

  49. Applicative and Normal-Order Evaluation (cont’d) • Example: #define DIVIDES(n,a) (!((n) % (a))) /* true iff n % a is zero */ • Preprocessor replaces DIVIDES (x,y+z) (textually!, no evaluation) with (!((x) % (y+z)))

  50. Applicative and Normal-Order Evaluation (cont’d) • Parentheses (n), (a) are crucial. Without them, DIVIDES (x,y+z) is replaced with (!(x % y+z)) which is equivalent to (!((x % y)+z))

More Related