CS5205: Foundations in Programming Languages Lambda Calculus CS5205 Lambda Calculus 1 Lambda Calculus • • • • • • • Untyped Lambda Calculus Evaluation Strategy Techniques - encoding, extensions, recursion Operational Semantics Explicit Typing Type Rules and Type Assumption Progress, Preservation, Erasure Introduction to Lambda Calculus: http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf http://www.cs.chalmers.se/Cs/Research/Logic/TypesSS05/Extra/geuvers.pdf CS5205 Lambda Calculus 2 Untyped Lambda Calculus • Extremely simple programming language which captures core aspects of computation and yet allows programs to be treated as mathematical objects. • Focused on functions and applications. • Invented by Alonzo (1936,1941), first used in a programming language (Lisp) by John McCarthy (1959). CS5205 Lambda Calculus 3 Functions without Names Usually functions are given a name (e.g. in language C): int plusone(int x) { return x+1; } …plusone(5)… However, function names can also be dropped: (int (int x) { return x+1;} ) (5) Notation used in untyped lambda calculus: (l x. x+1) (5) CS5205 Lambda Calculus 4 Syntax In purest form (no constraints, no built-in operations), the lambda calculus has the following syntax. t ::= terms variable abstraction application x lx.t tt This is simplest universal programming language! CS5205 Lambda Calculus 5 Conventions • Parentheses are used to avoid ambiguities. e.g. x y z can be either (x y) z or x (y z) • Two conventions for avoiding too many parentheses: • Applications associates to the left e.g. x y z stands for (x y) z • Bodies of lambdas extend as far as possible. e.g. l x. l y. x y x stands for l x. (l y. ((x y) x)). • Nested lambdas may be collapsed together. e.g. l x. l y. x y x can be written as l x y. x y x CS5205 Lambda Calculus 6 Scope • An occurrence of variable x is said to be bound when it occurs in the body t of an abstraction l x . t • An occurrence of x is free if it appears in a position where it is not bound by an enclosing abstraction of x. • Examples: x y ly. x y l x. x (l x. x x) (l x. x x) (l x. x) y (l x. x) x CS5205 (identity function) (non-stop loop) Lambda Calculus 7 Alpha Renaming • Lambda expressions are equivalent up to bound variable renaming. e.g. l x. x =a l y. y l y. x y =a l z. x z But NOT: l y. x y =a l y. z y • Alpha renaming rule: lx.E CS5205 =a l z . [x a z] E (z is not free in E) Lambda Calculus 8 Beta Reduction • An application whose LHS is an abstraction, evaluates to the body of the abstraction with parameter substitution. e.g. (l x. x y) z !b z y (l x. y) z !b (l x. x x) (l x. x x) !b y (l x. x x) (l x. x x) • Beta reduction rule (operational semantics): ( l x . t1 ) t2 !b [x a t2] t1 Expression of form ( l x . t1 ) t2 is called a redex (reducible expression). CS5205 Lambda Calculus 9 Evaluation Strategies • A term may have many redexes. Evaluation strategies can be used to limit the number of ways in which a term can be reduced. •Examples: - full beta reduction - normal order - call by name - call by value, etc • An evaluation strategy is deterministic, if it allows reduction with at most one redex, for any term. CS5205 Lambda Calculus 10 Full Beta Reduction • Any redex can be chosen, and evaluation proceeds until no more redexes found. • Example: (lx.x) ((lx.x) (lz. (lx.x) z)) denoted by id (id (lz. id z)) Three possible redexes to choose: id (id (lz. id z)) id (id (lz. id z)) id (id (lz. id z)) • Reduction: CS5205 id (id (lz. id z)) ! id (id (lz.z)) ! id (lz.z) ! lz.z ! Lambda Calculus 11 Normal Order Reduction • Deterministic strategy which chooses the leftmost, outermost redex, until no more redexes. • Example Reduction: id (id (lz. id z)) ! id (lz. id z)) ! lz.id z ! lz.z ! CS5205 Lambda Calculus 12 Call by Name Reduction • Chooses the leftmost, outermost redex, but never reduces inside abstractions. • Example: id (id (lz. id z)) ! id (lz. id z)) ! lz.id z ! CS5205 Lambda Calculus 13 Call by Value Reduction • Chooses the leftmost, innermost redex whose RHS is a value; and never reduces inside abstractions. • Example: id (id (lz. id z)) ! id (lz. id z) ! lz.id z ! CS5205 Lambda Calculus 14 Strict vs Non-Strict Languages • Strict languages always evaluate all arguments to function before entering call. They employ call-by-value evaluation (e.g. C, Java, ML). • Non-strict languages will enter function call and only evaluate the arguments as they are required. Call-by-name (e.g. Algol-60) and call-by-need (e.g. Haskell) are possible evaluation strategies, with the latter avoiding the reevaluation of arguments. • In the case of call-by-name, the evaluation of argument occurs with each parameter access. CS5205 Lambda Calculus 15 Programming Techniques in l-Calculus • Multiple arguments. • Church Booleans. • Pairs. • Church Numerals. • Enrich Calculus. • Recursion. CS5205 Lambda Calculus 16 Multiple Arguments • Pass multiple arguments one by one using lambda abstraction as intermediate results. The process is also known as currying. • Example: f = l(x,y).s f = l x. (l y. s) Application: f(v,w) (f v) w requires pairs as primitve types CS5205 requires higher order feature Lambda Calculus 17 Church Booleans • Church’s encodings for true/false type with a conditional: true false if • = l t. l f. t = l t. l f. f = l l. l m. l n. l m n Example: if true v w = (l l. l m. l n. l m n) true v w ! true v w = (l t. l f. t) v w ! v • Boolean and operation can be defined as: and = l a. l b. if a b false = l a. l b. (l l. l m. l n. l m n) a b false = l a. l b. a b false CS5205 Lambda Calculus 18 Pairs • Define the functions pair to construct a pair of values, fst to get the first component and snd to get the second component of a given pair as follows: pair fst snd = l f. l s. l b. b f s = l p. p true = l p. p false • Example: snd (pair c d) = (l p. p false) ((l f. l s. l b. b f s) c d) ! (l p. p false) (l b. b c d) ! (l b. b c d) false ! false c d ! d CS5205 Lambda Calculus 19 Church Numerals • Numbers can be encoded by: c0 c1 c2 c3 CS5205 = = = = : l s. l z. z l s. l z. s z l s. l z. s (s z) l s. l z. s (s (s z)) Lambda Calculus 20 Church Numerals • Successor function can be defined as: succ = l n. l s. l z. s (n s z) Example: succ c1 = (l n. l s. l z. s (n s z)) (l s. l z. s z) l s. l z. s ((l s. l z. s z) s z) ! l s. l z. s (s z) succ c2 = l n. l s. l z. s (n s z) (l s. l z. s (s z)) ! l s. l z. s ((l s. l z. s (s z)) s z) ! l s. l z. s (s (s z)) CS5205 Lambda Calculus 21 Church Numerals • Other Arithmetic Operations: plus = l m. l n. l s. l z. m s (n s z) times = l m. l n. m (plus n) c0 iszero = l m. m (l x. false) true • Exercise : Try out the following. plus c1 x times c0 x times x c1 iszero c0 iszero c2 CS5205 Lambda Calculus 22 Enriching the Calculus • We can add constants and built-in primitives to enrich lcalculus. For example, we can add boolean and arithmetic constants and primitives (e.g. true, false, if, zero, succ, iszero, pred) into an enriched language we call lNB: • Example: l x. succ (succ x) 2 lNB l x. true 2 lNB CS5205 Lambda Calculus 23 Recursion • Some terms go into a loop and do not have normal form. Example: (l x. x x) (l x. x x) ! (l x. x x) (l x. x x) ! … • However, others have an interesting property fix = l f. (l x. f (l y. x x y)) (l x. f (l y. x x y)) which returns a fix-point for a given functional. Given x =hx x is fix-point of h = fix h That is: CS5205 fix h ! h (fix h) ! h (h (fix h)) ! … Lambda Calculus 24 Example - Factorial • We can define factorial as: fact = l n. if (n<=1) then 1 else times n (fact (pred n)) = (l h. l n. if (n<=1) then 1 else times n (h (pred n))) fact = fix (l h. l n. if (n<=1) then 1 else times n (h (pred n))) CS5205 Lambda Calculus 25 Example - Factorial • • Recall: fact = fix (l h. l n. if (n<=1) then 1 else times n (h (pred n))) Let g = (l h. l n. if (n<=1) then 1 else times n (h (pred n))) Example reduction: fact 3 = = = = = = = = CS5205 fix g 3 g (fix g) 3 times 3 ((fix g) (pred 3)) times 3 (g (fix g) 2) times 3 (times 2 ((fix g) (pred 2))) times 3 (times 2 (g (fix g) 1)) times 3 (times 2 1) 6 Lambda Calculus 26 Formal Treatment of Lambda Calculus • Let V be a countable set of variable names. The set of terms is the smallest set T such that: 1. x 2 T for every x 2 V 2. if t1 2 T and x 2 V, then l x. t1 2 T 3. if t1 2 T and t2 2 T, then t1 t2 2 T • Recall syntax of lambda calculus: t ::= terms x variable l x.t abstraction tt application CS5205 Lambda Calculus 27 Free Variables • The set of free variables of a term t is defined as: FV(x) = {x} FV(l x.t) = FV(t) \ {x} FV(t1 t2) = FV(t1) [ FV(t2) CS5205 Lambda Calculus 28 Substitution • Works when free variables are replaced by term that does not clash: [x a l z. z w] (l y.x) = (l y. l x. z w) • However, problem if there is name capture/clash: [x a l z. z w] (l x.x) (l x. l z. z w) [x a l z. z w] (l w.x) (l w. l z. z w) CS5205 Lambda Calculus 29 Formal Defn of Substitution [x a s] x [x a s] y [x a s] (t1 t2) = s if y=x = y if yx = ([x a s] t1) ([x a s] t2) [x a s] (l y.t) = l y.t if y=x [x a s] (l y.t) = l y. [x a s] t if y x Æ y FV(s) [x a s] (l y.t) = [x a s] (l z. [y a z] t) if y x Æ y 2 FV(s) Æ fresh z CS5205 Lambda Calculus 30 Syntax of Lambda Calculus • Term: t ::= tt terms variable abstraction application l x.t terms abstraction value x l x.t • Value: t ::= CS5205 Lambda Calculus 31 Call-by-Value Semantics premise conclusion t1 ! t’1 (E-App1) t2 ! t’2 (E-App2) t1 t2 ! t’1 t2 v1 t2 ! v1 t’2 (l x.t) v ! [x a v] t CS5205 Lambda Calculus (E-AppAbs) 32 Call-by-Name Semantics t1 ! t’1 t1 t2 ! t’1 t2 (E-App1) (l x.t1) t2 ! [x a t2] t CS5205 Lambda Calculus (E-AppAbs) 33 Getting Stuck • Evaluation can get stuck. (Note that only values are labstraction) e.g. (x y) • In extended lambda calculus, evaluation can also get stuck due to the absence of certain primitive rules. (l x. succ x) true ! succ true ! CS5205 Lambda Calculus 34 Boolean-Enriched Lambda Calculus • Term: t ::= x l x.t tt true false if t then t else t • Value: v ::= l x.t true false CS5205 terms variable abstraction application constant true constant false conditional value abstraction value true value false value Lambda Calculus 35 Key Ideas • Exact typing impossible. if <long and tricky expr> then true else (l x.x) • Need to introduce function type, but need argument and result types. if true then (l x.true) else (l x.x) CS5205 Lambda Calculus 36 Simple Types • The set of simple types over the type Bool is generated by the following grammar: • T ::= Bool T!T • types type of booleans type of functions ! is right-associative: T1 ! T2 ! T3 CS5205 denotes Lambda Calculus T1 ! (T2 ! T3) 37 Implicit or Explicit Typing • Languages in which the programmer declares all types are called explicitly typed. Languages where a typechecker infers (almost) all types is called implicitly typed. • Explicitly-typed languages places onus on programmer but are usually better documented. Also, compile-time analysis is simplified. CS5205 Lambda Calculus 38 Steps for a Type System • Decide the static property to track. • Design the type annotation. • Design the type rules. • Prove soundness with respect to semantics • Design type inference algorithm, where possible CS5205 Lambda Calculus 39 Explicitly Typed Lambda Calculus • t ::= terms … l x : T.t … • v ::= • T ::= l x : T.t … Bool T!T CS5205 abstraction value abstraction value types type of booleans type of functions Lambda Calculus 40 Examples true l x:Bool . x (l x:Bool . x) true if false then (l x:Bool . True) else (l x:Bool . x) CS5205 Lambda Calculus 41 Erasure • The erasure of a simply typed term t is defined as: erase(x) erase(lx :T.t) erase(t1 t2) = = = x l x. erase(t) erase(t1) erase(t2) • A term m in the untyped lambda calculus is said to be typable in l! (simply typed l-calculus) if there are some simply typed term t, type T and context such that: erase(t)=m Æ ` t : T CS5205 Lambda Calculus 42 Typing Rule for Functions • First attempt: t2 : T2 l x:T1 . t2 : T1 ! T2 • But t2:T2 can assume that x has type T1 CS5205 Lambda Calculus 43 Need for Type Assumptions • Typing relation becomes ternary x:T1 ` t2 : T2 l x:T1.t2 : T1 ! T2 • For nested functions, we may need several assumptions. CS5205 Lambda Calculus 44 Typing Context • A typing context is a finite map from variables to their types. • Examples: x : Bool x : Bool, y : Bool ! Bool, z : (Bool ! Bool) ! Bool CS5205 Lambda Calculus 45 Type Rule for Abstraction Shall use to denote typing context. , x:T1 ` t2 : T2 ` l x:T1.t2 : T1 ! T2 CS5205 Lambda Calculus (T-Abs) 46 Other Type Rules • Variable x:T 2 (T-Var) ` x:T • Application ` t1 : T1 ! T2 ` t2 : T1 ` t1 t2 : T2 (T-App) • Boolean Terms. CS5205 Lambda Calculus 47 Typing Rules True : Bool (T-true) False : Bool (T-false) t1:Bool t2:T t3:T if t1 then t2 else t3 : T t : Nat (T-Succ) succ t : Nat CS5205 0 : Nat (T-Zero) (T-If) t : Nat (T-Pred) pred t : Nat Lambda Calculus t : Nat (T-Iszero) iszero t : Bool 48 Example of Typing Derivation x : Bool 2 x : Bool x : Bool ` x : Bool (T-Var) ` (l x : Bool. x) : Bool ! Bool (T-Abs) ` (l x : Bool. x) true : Bool CS5205 Lambda Calculus ` true : Bool (T-True) (T-App) 49 Canonical Forms • If v is a value of type Bool, then v is either true or false. • If v is a value of type T1 ! T2, then v=l x:T1. t2 where t:T2 CS5205 Lambda Calculus 50 Progress Suppose t is a closed well-typed term (that is {} ` t : T for some T). Then either t is a value or else there is some t’ such that t ! t’. CS5205 Lambda Calculus 51 Preservation of Types (under Susbtitution) If ,x:S ` t : T and ` s : S then ` [x a s]t : T CS5205 Lambda Calculus 52 Preservation of Types (under reduction) If ` t : T and t ! t’ then ` t’ : T CS5205 Lambda Calculus 53 Motivation for Typing • Evaluation of a term either results in a value or gets stuck! • Typing can prove that an expression cannot get stuck. • Typing is static and can be checked at compile-time. CS5205 Lambda Calculus 54 Normal Form A term t is a normal form if there is no t’ such that t ! t’. The multi-step evaluation relation !* is the reflexive, transitive closure of one-step relation. pred (succ(pred 0)) ! pred (succ 0) ! 0 CS5205 pred (succ(pred 0)) !* 0 Lambda Calculus 55 Stuckness Evaluation may fail to reach a value: succ (if true then false else true) ! succ (false) ! A term is stuck if it is a normal form but not a value. Stuckness is a way to characterize runtime errors. CS5205 Lambda Calculus 56 Safety = Progress + Preservation • Progress : A well-typed term is not stuck. Either it is a value, or it can take a step according to the evaluation rules. Suppose t is a well-typed term (that is t:T for some T). Then either t is a value or else there is some t‘ with t ! t‘ CS5205 Lambda Calculus 57 Safety = Progress + Preservation • Preservation : If a well-typed term takes a step of evaluation, then the resulting term is also well-typed. If t:T Æ t ! t‘ then t’:T . CS5205 Lambda Calculus 58