recitation 2: lambda & rules for application ----------------------------------------------------------------- lambda special form * what it looks like: list of formal parameters one or more expressions * what's the value of a lambda expression? rules for evaluating an expression: 1. if self-evaluating.. 2. if name.. 3. if special form... 4. if combination: * evaluate the subexpressions * apply the operator to the arguments rules for application: 1. if primitive procedure (built-in), just do it 2. if compound procedure * evaluate the body of the procedure with each formal parameter replaced by the corresponding argument value. * 1 or more expressions in the body are evaluated in order return the value of the last expression applicative order: evaluate all the arguments then apply normal order: fully expand and then reduce/evaluate ----------------------------------------------------------------- don't evaluate the lambda body until the application: (define a 5) (define foo (lambda () a)) (define a 6) a => 6 foo => procedure (foo) => 6 a => 6 (define foo (lambda (x) (/ x 0)) foo => procedure (foo 5) => error (define cube (lambda (x) (* x x x))) (define pythagoras (lambda (a b) (+ (sqrt (* a a) (* b b))))) ----------------------------------------------------------------------------------------------- syntactic sugar & infinite loops: (define (p) (p)) desugars to: (define p (lambda () (p))) (p) -> ? ----------------------------------------------------------------- why are these special forms? if, cond, and, or (define safe-divide (lambda (a b) (if (= b 0) 0 (/ a b)))) (define ratio-less-than (lambda (numer denom compare) (and (not (= denom 0)) (< (/ numer denom) compare)))) ----------------------------------------------------------------- what can we deduce about the ? (define foo ?) foo => 6 6 (foo 2) => 6 (lambda (x) (* x 3)) (+ 2 (foo)) => 6 (lambda () 4) (foo 10) => 10 (foo +) => proc (define foo (lambda (x) x)) (foo -5 3) => 5 (foo 2 7) => 2 (foo 7 4) => -4 (define foo (lambda (a b) (foo -10 -4) => 4 (if (< a b) (abs a) (- (abs b)))) (foo 4) => 6 (define foo (lambda (x) (foo 5) => 7 (cond ((= x 4) 6) ((= x 5) 7) ((= 6 x) +) ((= 7 x) (/ 1 0))))) (foo 6) => error, divide by zero (foo 7) => proc ----------------------------------------------------------------- different ways of writing the same thing (define a-plus-abs-b (lambda (a b) (+ a (abs b)))) (define a-plus-abs-b (lambda (a b) (if (> a b) (+ a b) (- a b)))) (define a-plus-abs-b (lambda (a b) ((if (> a b) + -) a b))) ----------------------------------------------------------------- (post-fix 4 5 +) => 9 (post-fix 3 4 <) => #t (define post-fix (lambda (arg1 arg2 op) (op arg1 arg2))) ----------------------------------------------------------------- (define print-num (lambda (x) (if (= x 0) "zero" (if (= x 1) "one" (if (= x 2) "two" (if (= x 3) "three" "can't count that high")))))) (define print-num (lambda (x) (cond ((= x 0) "zero") ((= x 1) "one") ((= x 2) "two") ((= x 3) "three") ((= x 4) "four") ((= x 5) "five") ((= x 6) "six") ((= x 7) "seven") ((= x 8) "eight") ((= x 9) "nine")))) -----------------------------------------------------------------------------------------------