TDDC74 Programmering: Abstraktion och modellering VT 2015 Johannes Schmidt Institutionen för datavetenskap Linköpings universitet 1 Lecture 2 Procedures and processes recursive descriptions recursive and iterative processes scope of names SICP 1, Del 2 2 Organisation For each lab assignment, several lab sessions are scheduled Maybe not all are needed, that depends on you, but usually even more time is needed The duggor are only for this year’s students (i.e., those taking the course for the first time) All others have to take the usual exam 3 2014s course evaluation Overall grade: 3.69 / 5 Lecture slides should be online before the lecture is given Too few introduction to OOP (object oriented programming) Many struggled with svn Mixing English with Swedish on lecture slides is confusing 4 2015s taken measures Old lecture slides are online. When bigger changes occur also the new ones will be online before the lecture More introduction to OOP (object oriented programming) Better and more introduction and information about svn Lecture slides purely in English 5 Assigning a name To numeric variables: (define foo 5) To procedures: (define bar (lambda (n) (+ n 4)) or usually (define bar (lambda (n) (+ n 4)) 6 Recursion Recursion is a way to make the computer loop Recursion is a way to break down to simpler (smaller) problems A computation is defined in terms of itself A termination condition is always required Very common in math, e.g., n! = n * (n-1)! when n > 0 0! = 1 7 0! = 1, n! = n * (n-1)! (define fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1)))))) (fact 4) 8 Substitution model Apply substitution to compute (fact 4): (define fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1)))))) (fact 4) (* 4 (fact 3)) (* 4 (* 3 (fact 2))) (* 4 (* 3 (* 2 (fact 1)))) (* 4 (* 3 (* 2 (* 1 (fact 0))))) (* 4 (* 3 (* 2 (* 1 1)))) (* 4 (* 3 (* 2 1))) (* 4 (* 3 2)) (* 4 6) 24 9 Procedures and processes recursive processes iterative processes 10 Procedures and processes When a procedure is evaluated, a process is generated 11 trace.ss (require (lib "trace.ss")) (trace square) (trace fact) 12 Linear recursive processes Contains a call to itself Every recursive call creates a delayed operation The time complexity (length of computation time) grows linearly relativly to the parameters size. In Big-Ohnotation (ordonotation): O(n) The space complexity (required memory) grows linearly relative to the parameters size. In Big-Oh-notation: O(n) The state of the computation is described by variables and current evaluation information 13 Linear recursive processes (define fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1)))))) -> Delivers a linear recursive process: Space complexity grows linearly relative to the parameters size: (fact 4) (* 4 (fact 3)) (* 4 (* 3 (fact 2))) (* 4 (* 3 (* 2 (fact 1)))) (* 4 (* 3 (* 2 (* 1 (fact 0))))) (* 4 (* 3 (* 2 (* 1 1)))) (* 4 (* 3 (* 2 1))) (* 4 (* 3 2)) (* 4 6) 24 Iterative factorial function Input : n Output: result = n! temp := 1 count := 1 Repeat temp := temp * count count := count + 1 Until count > n result := temp 15 Iterative factorial function (define fact-iter (lambda (n) (fact-help 1 1 n))) (define fact-help (lambda (temp count n) (if (> count n) temp (fact-help (* temp count) (+ count 1) n)))) In the extra parameter temp we store the intermediate result of the computation and in count we count the number of steps to be performed. 16 Substitution model (define fact-iter (lambda (n) (fact-help 1 1 n))) (fact-iter (fact-help (fact-help (fact-help (fact-help (fact-help (fact-help (fact-help (fact-help (fact-help 24 4) 1 1 4) (* 1 1) 1 2 4) (* 1 2) 2 3 4) (* 2 3) 6 4 4) (* 6 4) 24 5 4) (define fact-help (lambda (temp count n) (if (> count n) temp (fact-help (* temp count) (+ count 1) n)))) (+ 1 1) 4) (+ 2 1) 4) (+ 3 1) 4) (+ 4 1) 4) 17 Linear iterative processes a recursive call the recursive call does not delay the computation The time complexity grows linearly relative to the parameters size. In Big-Oh-notation: O(n) The space complexity is independent of the parameters size. In Big-Oh-notation: O(1) The state of the computation can be described by just the values of some variables, no information about the current evaluation progress is needed 18 Linear iterative processes (define fact-iter (lambda (n) (fact-iter 1 1 n))) (define fact-help (lambda (temp count n) (if (> count n) temp (fact-help (* temp count) (+ count 1) n)))) -> Delivers a linear iterative process: The space complexity is independent of the parameters size: (fact-iter (fact-help (fact-help (fact-help (fact-help (fact-help (fact-help (fact-help (fact-help (fact-help 24 4) 1 1 4) (* 1 1) 1 2 4) (* 1 2) 2 3 4) (* 2 3) 6 4 4) (* 6 4) 24 5 4) (+ 1 1) 4) (+ 2 1) 4) (+ 3 1) 4) (+ 4 1) 4) Fibonacci Numbers 0, 1, 1, 2, 3, 5, 8, 13, ... F0 = 0 F1 = 1 Fn = Fn-1 + Fn-2 (define fib (lambda (n) (cond ((= n 0) 0) ((= n 1) 1) (else (+ (fib (- n 1)) (fib (- n 2))))))) 20 Tree Recursive Process (fib 5) (+ (fib 4) (fib 3)) (+ (+ (fib 3) (fib 2)) (fib 3)) (+ (+ (+ (fib 2) (fib 1))(fib 2)) (fib 3)) (+ (+ (+ (+ (fib 1) (fib 0))(fib 1))...)...) 21 Tree Recursive Processes Multiple recursive calls in one expression Delayed operations Timecomplexity grows exponentially O(kn) Space complexity grows linearly O(n) 22 Iterative Fibonacci (define fibi (lambda (n) (cond ((= n 0) 0) ((= n 1) 1) (else (fiter n 0 1 1))))) (define fiter (lambda (n f0 f1 count) (if (= count n) f1 (fiter n f1 (+ f0 f1) (+ count 1))))) 23 recursive procedure != recursive process A recursive process is necessarily generated by a recursive procedure. But a recursive procedure does not necessarily generate a recursive process (see e.g. fact-iter) 24 Procedures without parameters (define random-number (lambda () (random 10))) (random-number) > 6 25 Scope (define add10 (lambda (number) (+ number 10))) The scope of ’number’ is the body of this procedure and it can only be used there (add10 3) > 13 number Error: reference to undefined identifier: number 26 Scope: local vs global (define number 23) (define add10 (lambda (number) (+ number 10))) (add10 15) > 25 (add10 number) > 33 27 Shadowing (define number 23) (define add10 (lambda (number) (+ number 10))) add10:s the definition of number, overshadows (or overrides) the global value of number 28 LET, LET* let and let* are used in order to create local scopes in which one evaluates certain code (let ( (<para1> <exp1>) (<para2> <exp2>) … (<paran> <expn>)) <body>) let binds its parameteters parallel, at the same time, whereas let* binds sequentially 29 LET example (define distance (lambda (x1 y1 x2 y2) (sqrt (+ (square (- x2 x1)) (square (- y2 y1)))))) The code becomes more readable if we replace (- x2 x1) by dx and (- y2 y1) by dy (define distance (lambda (x1 y1 x2 y2) (let ((dx (- x2 x1)) (dy (- y2 y1))) (sqrt (+ (square dx) (square dy))))) 30 LET is syntactic sugar (let ((a 5)) (* a 2)) is equivalent to ((lambda (a) (* a 2)) 5) 31 LET is syntactic sugar (define distance (lambda (x1 y1 x2 y2) (let ((dx (- x2 x1)) (dy (- y2 y1))) (sqrt (+ (square dx) (square dy)))))) is equivalent to (define distance2 (lambda (x1 y1 x2 y2) ((lambda (dx dy) (sqrt (+ (square dx) (square dy)))) (- x2 x1) (- y2 y1))) 32 LET vs LET* (define x 5) (define (f) (let ((x 1) (y (* x x))) (+ x y))) (define (g) (let* ((x 1) (y (* x x))) (+ x y))) > (f) 26 > (g) 2 33