Aoucemets HW6 due today HW7 is out A team assigmet Submitty page will be up toight Fuctioal correctess: 75%, Commets : 25% Last class Equality testig eq? vs. equal? Higher-order fuctios map, foldr, foldl Tail recursio Fall 18 CSCI 4430, A Milaova/BG Ryder 1 Fall 18 CSCI 4430, A Milaova/BG Ryder 2 Today s Lecture Outlie Fuctioal Programmig with Scheme Read: Scott, Chapter 11, Scott, 3.6 Exercises with map, foldl ad foldr Tail recursio Bidig with let, let*, ad letrec Scopig i Closures Scopig, revisited 3 Fall 18 CSCI 4430, A Milaova/BG Ryder 4 Exercises (foldr op lis id) Exercises (foldl op lis id) ( e 1 e -1 e ) id ( e 1 e -1 ) res 1 ( e 1 ) res -1 res Write rev, which reverses a list, usig a sigle call to foldr (defie (rev lis) (foldr ) ) Fall 18 CSCI 4430, A Milaova/BG Ryder 5 id ( e 1 e 2 e 3 e ) id 1 ( e 2 e 3 e ) id 2 ( e 3 e ) Write le, which computes legth of list, usig a sigle call to foldl (defie (le lis) (foldl ) ) id -1 ( e ) id 6 1
Exercises (defie (foldl op lis id) (if (ull? lis) id (foldl op (cdr lis) (op id (car lis)))) ) Write flatte3 usig map ad foldl/foldr Exercises (defie (IP a b) (Isert+ (ApplyToAll* (Traspose a b)))) ;;Example: (traspose ((1 2 3) (6 5 4))) yields ;; ((1 6) (2 5) (3 4)) (defie (traspose a b) Write flatte4 this time usig foldl but ot map. ;; Example: (apply-to-all* ((1 6) (2 5) (3 4))) ;; yields (6 10 12) (defie (apply-to-all* lis) Fall 18 CSCI 4430, A Milaova/BG Ryder 7 8 Exercises Write a fuctio that couts the appearaces of symbols a, b ad c i a list of flat lists (cout-sym ((a b) (c a) (a b d)) yields ((a 3) (b 2) (c 1)) Natural idea: use map ad fold foldr vs. foldl (defie (foldr op lis id) (if (ull? lis) id (op (car lis) (foldr op (cdr lis) id)) )) (defie (foldl op lis id) (if (ull? lis) id (foldl op (cdr lis) (op id (car lis))) )) map ad fold (also kow as reduce), are the foudatio of Google s MapReduce model Caoical MapReduce example [Dea ad Ghemawat OSDI 04] couts appearaces of certai words i a set of documets 9 Compare uderlied portios of these two fuctios foldr cotais a recursive call, but it is ot the etire retur value of the fuctio foldl returs the value obtaied from the recursive call to itself! Fall 18 CSCI 4430, A Milaova/BG Ryder 10 Tail Recursio Tail Recursio: Two Defiitios of Legth If the result of a fuctio is computed without a recursive call OR it is the result of a immediate recursive call, the the fuctio is said to be tail recursive E.g., foldl Tail recursio ca be implemeted efficietly Result is accumulated i oe of the argumets, ad stack frame creatio ca be avoided! implemetatios are required to be properly tail-recursive Fall 18 CSCI 4430, A Milaova/BG Ryder 11 (defie (le lis) (if (ull? lis) 0 (+ 1 (le (cdr lis))))) (le '(3 4 5)) (defie (leh lis acc) (if (ull? lis) acc (leh (cdr lis) (+ 1 acc)))) (defie (le lis) (leh lis 0)) (le '(3 4 5)) Leh is tail recursive. acc accumulates the legth Fall 18 CSCI 4430, A Milaova/BG Ryder 12 2
Tail Recursio: Two Defiitios of Factorial Let Expressios (defie (factorial ) (cod ((zero? ) 1) ((eq? 1) 1) (else (* (factorial (- 1)))))) (defie (fact2 acc) (cod ((zero? ) 1) ((eq? 1) acc) (else (fact2 (- 1) (* acc))))) (defie (factorial ) (fact2 1)) Let-expr ::= ( let ( Bidig-list ) S-expr1 ) Let*-expr ::= ( let* ( Bidig-list ) S-expr1 ) Bidig-list ::= ( Var S-expr ) { ( Var S-expr ) } let ad let* expressios defie a bidig betwee each Var ad the S-expr value, which holds durig executio of S-expr1 let evaluates the S-exprs i curret eviromet i parallel ; Vars are boud to fresh locatios holdig the results let* evaluates the S-exprs from left to right fact2 is tail recursive Associate values with variables for the local computatio Fall 18 CSCI 4430, A Milaova/BG Ryder 13 Fall 18 CSCI 4430, A Milaova/BG Ryder 14 Questios (let ((x 2)) (* x x)) yields 4 (let ((x 2)) (let ((y 1)) (+ x y)) ) yields what? (let ((x 10) (y (* 2 x))) (* x y)) yields what? Let Expressios Letrec-expr ::= ( letrec ( Bidig-list ) S-expr1 ) Bidig-list ::= ( Var S-expr ) { ( Var S-expr ) } letrec Vars are boud to fresh locatios holdig udefied values; S-exprs are evaluated i parallel i curret eviromet letrec allows for defiitio of mutually recursive fuctios (let* ((x 10) (y (* 2 x))) (* x y)) yields what? Fall 18 CSCI 4430, A Milaova/BG Ryder 15 (letrec (( eve? (lambda () (if (zero? ) #t (odd? (- 1)))) ) ( odd? (lambda () (if (zero? ) #f (eve? (- 1)))) ) ) (eve? 88) ) Fall 18 CSCI 4430, A Milaova/BG Ryder 16 Regios (Scopes) i let, let* ad letrec give rise to block structure They have the same sytax but defie differet regios (scopes) What s the scope of a let bidig (x S-epxr)? Regio where bidig is active: body of let Scope of a let* bidig (x S-epxr)? Regio: all bidigs to the right plus body of let* Scope of a letrec bidig (x S-epxr)? Regio: etire letrec expressio Let Itroduces Nested Scopes (let ((x 10)) ;causes x to be boud to 10 (let ((f (lambda (a) (+ a x))) ;causes f to be boud to a lambda expressio (let ((x 2)) (f 5) ) )) Assumig that Scheme uses static scopig, what would this expressio yield? Fall 18 CSCI 4430, A Milaova/BG Ryder 17 Fall 18 CSCI 4430, A Milaova/BG Ryder 18 3
Questio (defie (f z) (let* ( (x 5) (f (lambda (z) (* x z))) ) (map f z) ) ) What does this fuctio do? Aswer: takes a list of umbers, z, ad maps it to the x*5 list. E.g., (f (1 2 3)) yields (5 10 15). Scopig i: Two Choices (let ((x 10)) (let ((f (lambda (a) (+ a x)))) (let ((x 2)) (* x (f 3) ) ) ) a is a boud variable x is a free variable; must be foud i outer scope With static scopig it evaluates to (* x ((lambda (a)(+ a x)) 3)) --> (* 2 ((lambda (a)(+ a 10)) 3) ) -->??? With dyamic scopig it evaluates to (* x ((lambda (a)(+ a x)) 3)) --> (* 2 ((lambda (a)(+ a 2)) 3) ) -->??? Fall 18 CSCI 4430, A Milaova/BG Ryder 19 20 Scheme Chose Static Scopig (let ((x 10)) (let ((f (lambda (a) (+ a x)))) (let ((x 2)) (* x (f 3) ) ) ) f is a closure: The fuctio value: (lambda (a) (+ a x)) The eviromet: { x 10 } Scheme chose static scopig: (* x (lambda (a)(+ a x) 3)) --> (* 2 ((lambda (a)(+ a 10) 3) ) --> 26 21 Closures A closure is a fuctio value plus the eviromet i which it is to be evaluated Fuctio value: e.g., (lambda (x) (+ x y)) Eviromet cosists of bidigs for variables ot local to the fuctio; thus, closure ca evetually be evaluated: e.g., { y 2 } A closure ca be used as a fuctio Applied to argumets Passed as a argumet Retured as a value Fall 18 CSCI 4430, A Milaova/BG Ryder 22 Closures Normally, whe let expressio exits, its bidigs disappear Closure bidigs (i.e., bidigs part of a closure) are special Whe let exits, bidigs become iactive, but they do ot disappear Whe closure is called, bidigs become active Closure bidigs are immortal (let ((x 5)) (let (( f (let ((x 10)) (lambda () x ) ) )) Lecture Outlie Exercises with map, foldl ad foldr Tail recursio Bidig with let, let*, ad letrec Scopig i Closures Scopig, revisited (list x (f) x (f)) ) ) 23 Fall 18 CSCI 4430, A Milaova/BG Ryder 24 4
Scopig, revisited (Scott, Ch. 3.6) We discussed the two choices for mappig o-local variables to locatios Static scopig (early bidig) ad Dyamic scopig (late bidig) Most laguages choose static scopig Fall 18 CSCI 4430, A Milaova/BG Ryder 25 Scopig, revisited Whe we discussed scopig earlier, we assumed that fuctios were third-class values (i.e., fuctios caot be passed as argumets or retured from other fuctios) Whe fuctios are third-class values Whe fuctios are third-class values, the fuctio s static referece eviromet (i.e., closure bidigs) is available o the stack. Fuctio caot outlive its referecig eviromet! 26 Fuctios as Third-Class Values ad Static Scopig program a, b, c: iteger; procedure P c: iteger; procedure S c, d: iteger; procedure R ed R; R(); ed S; R(); S(); ed P; procedure R a: iteger; = a, b, c; ed R; ; P(); ed program mai --- --- a b c mai.p c mai.r a Static Scopig: a boud to R.a, b to mai.b, c to mai.c 27 Scopig, revisited Fuctios as first-class values Static scopig is more ivolved. Fuctio value may outlive static referecig eviromet! Therefore, eed immortal closure bidigs I laguages that choose static scopig, local variables must have ulimited extet (i.e., whe stack frame is popped, local variables do ot disappear!) 28 Scopig, revisited I fuctioal laguages local variables typically have ulimited extet I imperative laguages local variables typically have limited extet (i.e., whe stack frame is popped, local variables disappear) Imperative laguages (Fortra, Pascal, C) disallow truly first-class fuctio values More ad more laguages do allow first-class fuctios, e.g., Java 8, C++11 Fall 18 CSCI 4430, A Milaova 29 More o Dyamic Scopig Shallow bidig vs. deep bidig Dyamic scopig with shallow bidig Referece eviromet for fuctio/routie is ot created util the fuctio is called I.e., all o-local refereces are resolved usig the most-recet-frame-o-stack rule Shallow bidig is usually the default i laguages with dyamic scopig All examples of dyamic scopig we saw so far used shallow bidig 30 5
More o Dyamic Scopig Dyamic scopig with deep bidig Whe a fuctio/routie is passed as a argumet, the code that passes the fuctio/ routie has a particular referece eviromet (the curret oe!) i mid. It passes this referece eviromet alog with the fuctio value (it passes a closure). Example v : iteger := 10 people : database prit_routie (p : perso) if p.age > v write_perso(p) other_routie (db : database, P : procedure) v : iteger := 5 foreach record r i db P(r) Fall 18 CSCI 4430, A Milaova 31 other_routie(people, prit_routie) /* call i mai */ 32 Exercise Evaluatio Order (defie A (lambda () (let* ((x 2) (C (lambda (P) (let ((x 4)) (P) ))) (D (lambda () x)) (B (lambda () (let ((x 3)) (C D))))) (B)))) Whe we call > (A) i the iterpreter, what gets prited? What would get prited if Scheme used dyamic scopig with shallow bidig? Dyamic scopig ad deep bidig? 33 (defie (square x) (* x x)) Applicative-order (also referred to as eager) evaluatio Evaluates argumets before fuctio value (square (+ 3 4)) => (square 7) => (* 7 7) => 49 Fall 18 CSCI 4430, A Milaova/BG Ryder 34 Evaluatio Order (defie (square x) (* x x)) Normal-order (also referred to as lazy) evaluatio Evaluates fuctio value before argumets (square (+ 3 4)) => (* (+ 3 4) (+ 3 4)) => (* 7 (+ 3 4)) => (* 7 7) 49 uses applicative-order evaluatio 35 So Far Essetial fuctioal programmig cocepts Reductio sematics Lists ad recursio Higher-order fuctios Map ad fold (also kow as reduce) Evaluatio order Fall 18 CSCI 4430, A Milaova/BG Ryder 36 6
Comig Up Lambda calculus: theoretical foudatio of fuctioal programmig Haskell Algebraic data types ad patter matchig Lazy evaluatio Type iferece Moads Fall 18 CSCI 4430, A Milaova/BG Ryder 37 Fall 18 CSCI 4430, A Milaova/BG Ryder 38 7