CSC151.01 2006S, Class 12: Recursion, Revisited Admin: * Don't forget tomorrow's convo. * I've made slight rearrangements to the schedule to accomodate a bit more time for recursion. * Today's pedagogical problem: * Do I tell you that recursion is hard, which makes you react as if it's hard. * Do I tell you that it's easy, which may frustrate you if you fail to find it so? * We may be getting a bit out of synch with the other 151. We should get back in synch in about a week. * Reading for Friday: Re-read recursion (and bring questions)! Overview: * Detour: Scheme's Evaluation Strategy. * Example: Difference. * Q&A. * Lab. /Evaluating Expressions/ * Scheme has a variety of rules for evaluating expressions * Some simple rules * If you see a "primitive" value (number, boolean, characters, strings, ) just use that value * The value of 5 is 5 * The value of "foo" is "foo" * The value of 'bar is bar * If you see the name of a value, look up the named value and evaluate it * If we know (define a 5) * The value of a is 5 * Some complex rules * If you see a procedure application (name-of-procedure param1 param2 ... paramn) * (1) Evaluate all the parameters * (2) Apply the procedure * If you see a "keyword application" (and, or, if, cond), follow the rules for that keyword * How do we apply a procedure? * Built-in procedures: Follow the rules hidden behind the scenes * User-defined procedures * Terminology (define name (lambda (param1 param2 ... paramn) body)) - *Formal* parameters "formals" (name param1 param2 ... paramn) - *Actual* parameters "actuals" * When we apply a user defined procedure * Substitute actual parameters for formal parameters in the body * Evaluate the updated body (define double (lambda (x) (+ x x))) (define a 7) (double (double (* 3 (- a 2)))) -- Evaluate 3, we get (double (double (* 3 (- a 2)))) -- Value of a is 7 (double (double (* 3 (- 7 2)))) -- Evaluate 2, we get (double (double (* 3 (- 7 2)))) -- Evaluate (- 7 2), using the built-in - operation, it's 5 (double (double (* 3 5))) -- Evaluate (* 3 5) using the built-in * operations, it's 15 (double (double 15)) -- Substitute 15 for x in the body of double, and then evaluate the body (double (+ 15 15)) -- Evaluate (+ 15 15) using built-in + operation, it's 30 (double 30) -- Substitute 30 for x in the body of double, and then evaluate the body (+ 30 30) Note: Recursion is required for the definition of "evaluate" /Example: Sum and Difference/ (define sum (lambda (lst) (if (null? lst) 0 (+ (car lst) (sum (cdr lst)))))) (define newer-sum (lambda (lst) (newer-sum-helper (car lst) (cdr lst)))) (define newer-sum-helper (lambda (sum-so-far remaining-values) (if (null? remaining-values) sum-so-far (newer-sum-helper (+ sum-so-far (car remaining values)) (cdr remaining-values))))) (define difference (lambda (lst) (if (null? lst) 0 (- (car lst) (difference (cdr lst)))))) (define newer-difference (lambda (lst) (newer-difference-helper (car lst) (cdr lst)))) (define newer-difference-helper (lambda (difference-so-far remaining-values) (if (null? remaining-values) difference-so-far (newer-difference-helper (- difference-so-far (car remaining values)) (cdr remaining-values))))) /Notes on the Lab/ (define longer-string (lambda (str1 str2) (if (> (string-length str1) (string-length str2)) str1 str2)))