{- Max Sherman Section 05 Things to do: 1. Dynamic vs. Lexical Scope 2. "do" notation and the IO monad 3. Fixed point and the Y combinator -} {- Example #1 (define x 1) (define (g) x) (define (f) (let ([x 3]) (g))) (f) ; does this print 1 or 3? ; Lexical scope: ; The closure g has an environment where x maps to 1. ; Dynamic scope: ; To figure out what x maps to when we try to look it up, we need to go up ; g's "global stack of bindings", up to f, where we have the let binding, ; finding that x maps to 3. Example #2 (define evil (let ([x 2]) (lambda (y) (let ([z 3]) (set! x (+ 1 x)) (set! z (+ 1 z)) (+ x y z))))) (define ans (list (evil 1) (evil 1) (evil 1))) ; what is ans? Example #3 (like #2) (define x 100) (define (get-x) x) (define evil (let ([x 2]) (lambda (y) (let ([z 3]) (set! x (+ 1 x)) (set! z (+ 1 z)) (+ (get-x) y z))))) (define ans (list (evil 1) (evil 1) (evil 1))) ; what is ans if we use lexical scope? What about dynamic scope? -} -- IO Monad {- this is shorthand for the thing below main = do putStrLn "i am" putStrLn "cool" main = putStrLn "hi" >> putStrLn "swag" -} printsqrt2 = do putStr "the sqrt of 2 is " putStrLn (show (sqrt 2)) --desugared. printsqrt2' = putStr "the sqrt of 2 is " >> putStrLn (show (sqrt 2)) calcsqrt = do x <- readLn putStrLn "calculating the sqrt of x" putStrLn (show (sqrt x)) --desugared. calcsqrt' = readLn >>= \x -> putStrLn "calculating the sqrt of x" >> putStrLn (show (sqrt x)) -- Fixed Point Combinators --3. range 0 = [] range n = n : range (n - 1) -- OR MORE HELPFULLY range n = case n of 0 -> [] n -> n : range (n-1) --4. General strategy: abstract all parameters into lambdas, then abstract -- function name into a lambda. fix f = f (fix f) {- range n -----> range = \n -> case n of 0 -> [] n -> n : range (n-1) range = \r -> \n -> case n of 0 -> [] n -> n : r (n-1) -} range' = fix (\r -> \n -> case n of 0 -> [] n -> n : r (n - 1)) --5. {- (define (range n) (if (zero? n) null (cons n (range (sub1 n))))) 6. Recall that the strict Y combinator is (define Y (lambda (f) ((lambda (x) (f (lambda (v) ((x x) v)))) (lambda (x) (f (lambda (v) ((x x) v))))))) So use same procedure as you did with haskell and fix, abstract out parameters with lambdas. (define rangef (Y (lambda (r) (lambda (n) (if (zero? n) null (cons n (r (sub1 n)))))))) -}