CSC151.01 2006S, Class 21: Local Procedure Bindings Admin: * No reading for Monday * Assigned: Homework 8: Intersection. * Due: Exam 1. * EC: * Tuesday extra next week: Installing Linux * Football at 1:30 on Saturday * 12:45 on Saturday, Water Polo, Sport of Elites * Prospies? * Why should U. come to Grinnell instead of IAState or UMinn or some other enormous state institution with a D-I football team? * More attention from professors * Grinnell students graduate with approximately half the average debt of IAState students. * No common intellectual experience. * Customize your own education. Overview: * Why Have Local Procedures. * Creating Local Procedures. * An Example: Reverse. * Lab. /Review of Wednesday/ * It is useful to have named values that are "local" to a procedure * Safety: No one else can change them * Convenience: Reuse names * Encapsulation: It's all together * Avoids redundancy * It is equally useful to name procedures locally * Particularly kernels * let and let* don't cut it for recursive procedures * We must support local recursive procedures: letrec * Just like a let (or let*) (letrec ((name value) (name value) ... (name value) exp1 exp2 ... exp3)) * Except that the name/value pairs can define recursive procedures. (define reverse (lambda (lst) (reverse-helper null lst))) (define reverse-helper (lambda (so-far remaining) (if (null? remaining) so-far (reverse-helper (cons (car remaining) so-far) (cdr remaining))))) (define reverse (letrec ((h (lambda (so-far remaining) (if (null? remaining) so-far (h (cons (car remaining) so-far) (cdr remaining)))))) (lambda (lst) (h null lst)))) This is such a common pattern that we'll provide an alternate syntax (define proc (letrec ((kernel (lambda (param1 ... paramn) body))) (lambda (arg1 ... argm) (kernel initial1 .... initialn)))) ALternative! (It's just "syntactic sugar") (define proc (lambda (arg1 ... argm) (let kernel ((param1 initial1) (param2 initial2) ... (paramn initialn)) body))) /Lab/ * I *really* prefer that you define last-of-list recursively' ; If the list contains one element, ; return that elent ; Otherwise ; return the last element in the cdr * Here's what I'd like for 1.c. (letrec ((last-of-list (lambda (lst) ...))) (+ (last-of-list (list ...)) (last-of-list (list ...)) (last-of-list (list ...))))