
Evaluating declarations Programming Languages and n Evaluation uses an environment ρ Compilers (CS 421) n To evaluate a (simple) declaration let x = e n Evaluate expression e in ρ to value v n Then update ρ with x v: {x → v} + ρ Elsa L Gunter 2112 SC, UIUC http://courses.engr.illinois.edu/cs421 Based in part on slides by Mattox Beckman, as updated by Vikram Adve and Gul Agha 9/11/14 1 9/11/14 2 Evaluating expressions Eval of App with Closures in OCaml n Evaluation uses an environment ρ 1. Evaluate the right term to values, (v1,…,vn) n A constant evaluates to itself 2. In environment ρ, evaluate left term to n To evaluate an variable, look it up in ρ (ρ(v)) closure, c = <(x1,…,xn) → b, ρ> n To evaluate uses of +, _ , etc, eval args, 3. Match (x1,…,xn) variables in (first) argument then do operation with values (v1,…,vn) n Function expression evaluates to its closure 4. Update the environment ρ to n To evaluate a local dec: let x = e1 in e2 ρ’ = {x1 → v1,…, xn →vn}+ ρ n Eval e1 to v, then eval e2 using {x → v} + ρ 5. Evaluate body b in environment ρ’ 9/11/14 3 9/11/14 4 OCaml Example 1 OCaml Example 1 # (print_string "a"; # (print_string "a"; (fun x -> (print_string "b"; (fun x -> (print_string "b"; (fun y -> (print_string "c"; (fun y -> (print_string "c"; x + y))))) x + y))))) (print_string "d"; 3) (print_string "d"; 3) (print_string "e"; 5);; (print_string "e"; 5);; edabc- : int = 8 # 9/11/14 5 9/11/14 6 # let f = (print_string "a"; Your turn now (fun x -> (print_string "b"; (fun y -> (print_string "c"; x + y))))) in Try Problem 1 on HW3 let u = (print_string "d"; 3) in let g = f u in let v = (print_string "e"; 5) in g v;; 9/11/14 7 9/11/14 8 Higher Order Functions # let f = (print_string "a"; n A function is higher-order if it takes a function as an argument or returns one as (fun x -> (print_string "b"; a result (fun y -> (print_string "c"; n Example: x + y))))) in # let compose f g = fun x -> f (g x);; let u = (print_string "d"; 3) in val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> let g = f u in 'b = <fun> let v = (print_string "e"; 5) in g v;; n The type ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b is a higher order type because of adbec- : int = 8 ('a -> 'b) and ('c -> 'a) and -> 'c -> 'b 9/11/14 9 9/11/14 10 Thrice Thrice n Recall: n Recall: # let thrice f x = f (f (f x));; # let thrice f x = f (f (f x));; val thrice : ('a -> 'a) -> 'a -> 'a = <fun> val thrice : ('a -> 'a) -> 'a -> 'a = <fun> n How do you write thrice with compose? n How do you write thrice with compose? # let thrice f = compose f (compose f f);; val thrice : ('a -> 'a) -> 'a -> 'a = <fun> n Is this the only way? 9/11/14 11 9/11/14 12 Partial Application Lambda Lifting # (+);; n You must remember the rules for evaluation - : int -> int -> int = <fun> when you use partial application # (+) 2 3;; # let add_two = (+) (print_string "test\n"; 2);; - : int = 5 test # let plus_two = (+) 2;; val add_two : int -> int = <fun> val plus_two : int -> int = <fun> # plus_two 7;; # let add2 = (* lambda lifted *) - : int = 9 fun x -> (+) (print_string "test\n"; 2) x;; n Patial application also called sectioning val add2 : int -> int = <fun> 9/11/14 13 9/11/14 14 Lambda Lifting Partial Application and “Unknown Types” # thrice add_two 5;; n Recall compose plus_two: - : int = 11 # let f1 = compose plus_two;; # thrice add2 5;; val f1 : ('_a -> int) -> '_a -> int = <fun> test test n Compare to lambda lifted version: test # let f2 = fun g -> compose plus_two g;; - : int = 11 val f2 : ('a -> int) -> 'a -> int = <fun> n Lambda lifting delayed the evaluation of the n What is the difference? argument to (+) until the second argument was supplied 9/11/14 15 9/11/14 16 Partial Application and “Unknown Types” Partial Application and “Unknown Types” n ‘_a can only be instantiated once for an expression n ‘a can be repeatedly instantiated # f1 plus_two;; - : int -> int = <fun> # f2 plus_two;; # f1 List.length;; - : int -> int = <fun> Characters 3-14: # f2 List.length;; f1 List.length;; - : '_a list -> int = <fun> ^^^^^^^^^^^ This expression has type 'a list -> int but is here used with type int -> int 9/11/14 17 9/11/14 18 Lists n First example of a recursive datatype (aka Your turn now algebraic datatype) n Unlike tuples, lists are homogeneous in Try Problem 2 on HW3 type (all elements same type) 9/11/14 19 9/11/14 20 Lists Lists # let fib5 = [8;5;3;2;1;1];; n List can take one of two forms: val fib5 : int list = [8; 5; 3; 2; 1; 1] n Empty list, written [ ] # let fib6 = 13 :: fib5;; n Non-empty list, written x :: xs val fib6 : int list = [13; 8; 5; 3; 2; 1; 1] n x is head element, xs is tail list, :: called # (8::5::3::2::1::1::[ ]) = fib5;; “cons” - : bool = true n Syntactic sugar: [x] == x :: [ ] # fib5 @ fib6;; n [ x1; x2; …; xn] == x1 :: x2 :: … :: xn :: [ ] - : int list = [8; 5; 3; 2; 1; 1; 13; 8; 5; 3; 2; 1; 1] 9/11/14 21 9/11/14 22 Lists are Homogeneous Question # let bad_list = [1; 3.2; 7];; n Which one of these lists is invalid? Characters 19-22: let bad_list = [1; 3.2; 7];; 1. [2; 3; 4; 6] ^^^ 2. [2,3; 4,5; 6,7] This expression has type float but is here 3. [(2.3,4); (3.2,5); (6,7.2)] used with type int 4. [[“hi”; “there”]; [“wahcha”]; [ ]; [“doin”]] 9/11/14 23 9/11/14 24 Answer Functions Over Lists n Which one of these lists is invalid? # let rec double_up list = match list 1. [2; 3; 4; 6] with [ ] -> [ ] (* pattern before ->, expression after *) 2. [2,3; 4,5; 6,7] | (x :: xs) -> (x :: x :: double_up xs);; 3. [(2.3,4); (3.2,5); (6,7.2)] val double_up : 'a list -> 'a list = <fun> 4. [[“hi”; “there”]; [“wahcha”]; [ ]; [“doin”]] # let fib5_2 = double_up fib5;; val fib5_2 : int list = [8; 8; 5; 5; 3; 3; 2; 2; 1; § 3 is invalid because of last pair 1; 1; 1] 9/11/14 25 9/11/14 26 Functions Over Lists Question: Length of list # let silly = double_up ["hi"; "there"];; n Problem: write code for the length of the list val silly : string list = ["hi"; "hi"; "there"; "there"] n How to start? # let rec poor_rev list = let rec length l = match list with [] -> [] | (x::xs) -> poor_rev xs @ [x];; val poor_rev : 'a list -> 'a list = <fun> # poor_rev silly;; - : string list = ["there"; "there"; "hi"; "hi"] 9/11/14 27 9/11/14 28 Question: Length of list Question: Length of list n Problem: write code for the length of the list n Problem: write code for the length of the list n How to start? n What patterns should we match against? let rec length l = let rec length l = match l with match l with 9/11/14 29 9/11/14 30 Question: Length of list Question: Length of list n Problem: write code for the length of the list n Problem: write code for the length of the list n What patterns should we match against? n What result do we give when l is empty? let rec length l = let rec length l = match l with [] -> match l with [] -> | (a :: bs) -> | (a :: bs) -> 9/11/14 31 9/11/14 32 Question: Length of list Question: Length of list n Problem: write code for the length of the list n Problem: write code for the length of the list n What result do we give when l is empty? n What result do we give when l is not empty? let rec length l = let rec length l = match l with [] -> 0 match l with [] -> 0 | (a :: bs) -> | (a :: bs) -> 9/11/14 33 9/11/14 34 Question: Length of list n Problem: write code for the length of the list Your turn now n What result do we give when l is not empty? let rec length l = match l with [] -> 0 | (a :: bs) -> 1 + length bs Try Problem 1 on MP3 9/11/14 35 9/11/14 36 Same Length Same Length n How can we efficiently answer if two lists n How can we efficiently answer if two lists have the same length? have the same length? let rec same_length list1 list2 = match list1 with [] -> (match list2 with [] -> true | (y::ys) -> false) | (x::xs) -> (match list2 with [] -> false | (y::ys) -> same_length xs ys) 9/11/14 37 9/11/14 38 Structural Recursion Structural Recursion : List Example n Functions on recursive datatypes (eg lists) # let rec length list = match list tend to be recursive with [ ] -> 0 (* Nil case *) n Recursion over recursive datatypes generally | x :: xs -> 1 + length xs;; (* Cons case *) by structural recursion val length : 'a list -> int = <fun> n Recursive calls made to components of structure of the same recursive type # length [5; 4; 3; 2];; n Base cases of recursive types stop the recursion - : int = 4 of the function n Nil case [ ] is base case n Cons case recurses on component list xs 9/11/14 39 9/11/14 40 Forward Recursion Forward Recursion: Examples n In Structural Recursion, split input into components and (eventually) recurse # let rec double_up list = match list n Forward Recursion form of Structural with [ ] -> [ ] Recursion | (x :: xs) -> (x :: x :: double_up xs);; n In forward recursion, first call the function val double_up : 'a list -> 'a list = <fun> recursively on all recursive components, and # let rec poor_rev list = then build final result from partial results match list n Wait until whole structure has been with [] -> [] traversed to start building answer | (x::xs) -> poor_rev xs @ [x];; val poor_rev : 'a list -> 'a list = <fun> 9/11/14 41 9/11/14 42 Forward Recursion: Example Question # let rec map f list = n How do you write length with forward match list recursion? with [] -> [] let rec length l = | (h::t) -> (f h) :: (map f t);; val map : ('a -> 'b) -> 'a list -> 'b list = <fun> # map plus_two fib5;; - : int list = [10; 7; 5; 4; 3; 3] # map (fun x -> x - 1) fib6;; : int list = [12; 7; 4; 2; 1; 0; 0] 9/11/14 43 9/11/14 44 Question Question n How do you write length with forward n How do you write length with forward recursion? recursion? let rec length l
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages14 Page
-
File Size-