* Procedures, a built-in, first-class type of Scheme ** lambda makes procedures *** examples: ------------------------ ((lambda (x) x) 'y) ;Value: y ((lambda (x) (car x)) '(a b c)) ;Value: a *note: above is same as "car" (eta conversion) (lambda (x) (e1 x)) =def= e1, if x does not occur free in e1 ((lambda (x y) 0) 'a 'b) ;Value: 0 ((lambda () 5)) ; no arguments ;Value: 5 ------------------------ *** applicative order evaluation rule ** Procedures first-class in LISP *** examples --------------- (lambda (x) x) ; identity function ;Value: #[COMPOUND-PROCEDURE #x1A0418] (define id (lambda (x) x)) (id 1) ;Value: 1 ((lambda (y) y) 3) ;Value: 3 (define one 1) (define inc (lambda (x) (+ one x))) (inc 2) ;Value: 3 (set! one 2) ; mutation of global environment! (inc 2) ;Value: 4 ; closes over bindings, not values! ------------------- *** environment model *** functionals ------------------- ;; compose functional (define compose (lambda (f g) (lambda (x) (f (g x))))) ((compose car cdr) '(a b c)) ;Value: b ((compose car (compose cdr cdr)) '(a b c)) ;Value: c (define caddr (compose car (compose cdr cdr))) (caddr '(a b c)) ;Value: c ;; curry functional (define curry (lambda (f) (lambda (x) (lambda (y) (f x y))))) (((curry +) 1) 2) ;Value: 3 (define by2 ((curry *) 2)) (by2 5) ;Value: 10 ;; combinators (with historical names) (define B (curry compose)) (define W (lambda (f) (lambda (x) ((f x) x)))) (define twice (W B)) ((twice by2) 7) ;Value: 28 (define I (lambda (x) x)) (define K (lambda (c) (lambda (x) c))) ((K 3) 5) ;Value? (define S (lambda (f g) (lambda (x) (f x (g x))))) (define CS (curry S)) ; exercise: what is (S K K)? ;; applicative order Y combinator: (define Y (lambda (M) ((lambda (future) (M (lambda (arg) ((future future) arg)))) (lambda (future) (M (lambda (arg) ((future future) arg))))))) ------------------- * Lambda the Ultimate ** the Y-combinator can be used to make recursive functions ------------- (define oh-no (Y (lambda (recurse) (lambda (x) (recurse x))))) (define length (Y (lambda (recurse) (lambda (l) (cond ((null? l) 0) (else (+ 1 (recurse (cdr l))))))))) ------------- ** closures can be used to delay evaluation ------------- (define (if-closures e1 c2 c3) (if e1 (c2) (c3))) (if-closures #t (lambda () (+ 3 4)) (lambda () (oh-no #t))) ;Value: 7 -------------