✬ ✩ ✬ ✩ CIS 500 Software Foundations Recursion Fall 2005 2 November ✫ ✪ ✫ ✪ CIS 500, 2 November 1 CIS 500, 2 November 2 ✬ ✩ ✬ ✩ Recursion in λ → Example ff = λ ie:Nat → Bool. � In λ → , all programs terminate. (Cf. Chapter 12.) λ x:Nat. � Hence, untyped terms like omega and fix are not typable. if iszero x then true else if iszero (pred x) then false � But we can extend the system with a (typed) fixed-point operator... else ie (pred (pred x)); iseven = fix ff; iseven 7; ✫ ✪ ✫ ✪ CIS 500, 2 November 3 CIS 500, 2 November 4
✬ ✩ ✬ ✩ New syntactic forms New typing rules Γ ⊢ t : T t ::= ... terms fix t fixed point of t Γ ⊢ t 1 : T 1 → T 1 ( T-Fix ) Γ ⊢ fix t 1 : T 1 → t ′ New evaluation rules t − fix ( λ x:T 1 .t 2 ) ( E-FixBeta ) → [ x � → (fix ( λ x:T 1 .t 2 )) ] t 2 − → t ′ t 1 − 1 ( E-Fix ) → fix t ′ fix t 1 − 1 ✫ ✪ ✫ ✪ CIS 500, 2 November 5 CIS 500, 2 November 6 ✬ ✩ ✬ ✩ A more convenient form def = letrec x:T 1 =t 1 in t 2 let x = fix ( λ x:T 1 .t 1 ) in t 2 References letrec iseven : Nat → Bool = λ x:Nat. if iszero x then true else if iszero (pred x) then false else iseven (pred (pred x)) in iseven 7; ✫ ✪ ✫ ✪ CIS 500, 2 November 7 CIS 500, 2 November 8
✬ ✩ ✬ ✩ Mutability Basic Examples let r = ref 5 � In most programming languages, variables are mutable — i.e., a variable !r provides both r := 7 � a name that refers to a previously calculated value, and (r:=succ(!r); !r) � the possibility of overwriting this value with another (which will be (r:=succ(!r); r:=succ(!r); r:=succ(!r); r:=succ(!r); !r) referred to by the same name) � In some languages (e.g., OCaml), these two features are kept separate � variables are only for naming — the binding between a variable and its value is immutable � introduce a new class of mutable values (called reference cells or references) � at any given moment, a reference holds a value (and can be dereferenced to obtain this value) � a new value may be assigned to a reference ✫ ✪ ✫ ✪ CIS 500, 2 November 9 CIS 500, 2 November 10 ✬ ✩ ✬ ✩ Basic Examples Aliasing let r = ref 5 A value of type Ref T is a pointer to a cell holding a value of type T . !r r = r := 7 (r:=succ(!r); !r) (r:=succ(!r); r:=succ(!r); r:=succ(!r); r:=succ(!r); !r) 5 i.e., If this value is “copied” by assigning it to another variable, the cell pointed to ((((r:=succ(!r); r:=succ(!r)); r:=succ(!r)); r:=succ(!r)); !r) is not copied. r = s = 5 So we can change r by assigning to s : (s:=6; !r) ✫ ✪ ✫ ✪ CIS 500, 2 November 10-a CIS 500, 2 November 11
✬ ✩ ✬ ✩ Aliasing all around us The difficulties of aliasing Reference cells are not the only language feature that introduces the possibility The possibility of aliasing invalidates all sorts of useful forms of reasoning of aliasing. about programs, both by programmers... � arrays The function λ r:Ref Nat. λ s:Ref Nat. (r:=2; s:=3; !r) � communication channels always returns 2 unless r and s are aliases for the same cell. � I/O devices (disks, etc.) ...and by compilers: Code motion out of loops, common subexpression elimination, allocation of variables to registers, and detection of uninitialized variables all depend upon the compiler knowing which objects a load or a store operation could reference. High-performance compilers spend significant energy on alias analysis to try to establish when different variables cannot possibly refer to the same storage. ✫ ✪ ✫ ✪ CIS 500, 2 November 12 CIS 500, 2 November 13 ✬ ✩ ✬ ✩ The benefits of aliasing Example The problems of aliasing have led some language designers simply to disallow it c = ref 0 (e.g., Haskell). incc = λ x:Unit. (c := succ (!c); !c) But there are good reasons why most languages do provide constructs decc = λ x:Unit. (c := pred (!c); !c) involving aliasing: incc unit � efficiency (e.g., arrays) decc unit � “action at a distance” (e.g., symbol tables) o = {i = incc, d = decc} � shared resources (e.g., locks) in concurrent systems � etc. ✫ ✪ ✫ ✪ CIS 500, 2 November 14 CIS 500, 2 November 15
✬ ✩ ✬ ✩ let newcounter = Syntax λ _:Unit. let c = ref 0 in ::= t terms let incc = λ x:Unit. (c := succ (!c); !c) in unit unit constant let decc = λ x:Unit. (c := pred (!c); !c) in x variable let o = {i = incc, d = decc} in λ x:T.t abstraction o t t application ref t reference creation dereference !t t:=t assignment ✫ ✪ ✫ ✪ ... plus other familiar types, in examples. CIS 500, 2 November 16 CIS 500, 2 November 17 ✬ ✩ ✬ ✩ Typing Rules Another example BoolArray = Ref (Nat → Bool); Γ ⊢ t 1 : T 1 newarray = λ _:Unit. ref ( λ n:Nat.false); ( T-Ref ) Γ ⊢ ref t 1 : Ref T 1 : Unit → BoolArray lookup = λ a:BoolArray. λ n:Nat. (!a) n; Γ ⊢ t 1 : Ref T 1 : BoolArray → Nat → Bool ( T-Deref ) Γ ⊢ !t 1 : T 1 update = λ a:BoolArray. λ m:Nat. λ v:Bool. let oldf = !a in Γ ⊢ t 1 : Ref T 1 Γ ⊢ t 2 : T 1 a := ( λ n:Nat. if equal m n then v else oldf n); ( T-Assign ) : BoolArray → Nat → Bool → Unit Γ ⊢ t 1 :=t 2 : Unit ✫ ✪ ✫ ✪ CIS 500, 2 November 18 CIS 500, 2 November 19
✬ ✩ ✬ ✩ Evaluation Evaluation What is the value of the expression ref 0 ? What is the value of the expression ref 0 ? Crucial observation: evaluating ref 0 must do something. Otherwise, r = ref 0 s = ref 0 and r = ref 0 s = r would behave the same. ✫ ✪ ✫ ✪ CIS 500, 2 November 20 CIS 500, 2 November 20-a ✬ ✩ ✬ ✩ Evaluation Evaluation What is the value of the expression ref 0 ? What is the value of the expression ref 0 ? Crucial observation: evaluating ref 0 must do something. Crucial observation: evaluating ref 0 must do something. Otherwise, Otherwise, r = ref 0 r = ref 0 s = ref 0 s = ref 0 and and r = ref 0 r = ref 0 s = r s = r would behave the same. would behave the same. Specifically, evaluating ref 0 should allocate some storage and yield a Specifically, evaluating ref 0 should allocate some storage and yield a reference (or pointer) to that storage. reference (or pointer) to that storage. So what is a reference? ✫ ✪ ✫ ✪ CIS 500, 2 November 20-b CIS 500, 2 November 20-c
✬ ✩ ✬ ✩ The Store The Store A reference names a location in the store (also known as the heap or just the A reference names a location in the store (also known as the heap or just the memory). memory). What is the store? What is the store? � Concretely: An array of 8-bit bytes, indexed by 32-bit integers. ✫ ✪ ✫ ✪ CIS 500, 2 November 21 CIS 500, 2 November 21-a ✬ ✩ ✬ ✩ The Store The Store A reference names a location in the store (also known as the heap or just the A reference names a location in the store (also known as the heap or just the memory). memory). What is the store? What is the store? � Concretely: An array of 8-bit bytes, indexed by 32-bit integers. � Concretely: An array of 8-bit bytes, indexed by 32-bit integers. � More abstractly: an array of values � More abstractly: an array of values � Even more abstractly: a partial function from locations to values. ✫ ✪ ✫ ✪ CIS 500, 2 November 21-b CIS 500, 2 November 21-c
✬ ✩ ✬ ✩ Locations Syntax of Terms Syntax of values: ::= t terms ::= v values unit unit constant unit unit constant variable x λ x:T.t abstraction value λ x:T.t abstraction l store location t t application ref t reference creation !t dereference t:=t assignment l store location ✫ ✪ ✫ ✪ ... and since all values are terms... CIS 500, 2 November 22 CIS 500, 2 November 23 ✬ ✩ ✬ ✩ Aside Evaluation Does this mean we are going to allow programmers to write explicit locations The result of evaluating a term now depends on the store in which it is in their programs?? evaluated. Moreover, the result of evaluating a term is not just a value — we must also keep track of the changes that get made to the store. No: This is just a modeling trick. We are enriching the “source language” to include some run-time structures, so that we can continue to formalize I.e., the evaluation relation should now map a term and a store to a reduced evaluation as a relation between source terms. term and a new store. → t ′ | µ ′ t | µ − We use the metavariable µ to range over stores. Aside: If we formalize evaluation in the big-step style, then we can add locations to the set of values (results of evaluation) without adding them to the ✫ ✪ ✫ ✪ set of terms. CIS 500, 2 November 24 CIS 500, 2 November 25
Recommend
More recommend