170 likes | 415 Views
Types and Programming Languages. Lecture 7. Simon Gay Department of Computing Science University of Glasgow. 2006/07. Lambda Calculus with Types. We introduce function types : A B is the type of functions with a parameter of type A and a result of type B.
E N D
Types and Programming Languages Lecture 7 Simon Gay Department of Computing Science University of Glasgow 2006/07
Lambda Calculus with Types We introduce function types: A B is the type of functions with a parameter of type A and a result of type B. Types are defined by this grammar: T ::= int | bool | T T By convention, associates to the right, so that A B C means A (B C). Example int int int curried function of two arguments (int int) int function which is given a function Types and Programming Languages Lecture 7 - Simon Gay
Typing Rules for Functions To make it easier to define the typing rules, we will modify the syntax so that a -abstraction explicitly specifies the type of its parameter. v ::= integer literal | true | false | x:T.e e ::= v | x | e + e | e == e | e & e | if e then e else e | ee T ::= int | bool | T T Types and Programming Languages Lecture 7 - Simon Gay
Typing Rules for Functions The rules are similar to those in SFL, but simpler because we have function types. (T-Abs) (T-App) We also need the typing rules for SEL, with environments added. The resulting system is called the simply typed lambda calculus. (A broad term: anything with T-Abs, T-App, and at least one base type or ground type such as int or bool.) Types and Programming Languages Lecture 7 - Simon Gay
Simply Typed Lambda Calculus true : bool false : bool v : int if v is an integer literal (T-Var) (T-Plus) (T-And) (T-Eq) (T-If) (T-Abs) (T-App) Types and Programming Languages Lecture 7 - Simon Gay
Examples Types and Programming Languages Lecture 7 - Simon Gay
Termination If a typable closed term of the simply typed lambda calculus is executed, it is guaranteed to terminate. If e:T then for some value v, e * v. (See Pierce chapter 12 for a proof.) This result is usually called strong normalization and it is true no matter which reduction strategy is used. It might seem surprising, because we know that recursion can be expressed in the lambda calculus (and we have even seen a non-terminating reduction sequence). The answer is that any term containing xx is untypable. Types and Programming Languages Lecture 7 - Simon Gay
xx is untypable If xx were typable, with some type T, then there would be a derivation of x:U xx :T for some type U. What would this derivation look like? We can see that U must be of the form U T but this is not possible (unless we have recursive types, which are coming later). Types and Programming Languages Lecture 7 - Simon Gay
Recursion in simply typed lambda calculus If we want to use the fixed point operator Y to express recursive function definitions in the simply typed lambda calculus then we must introduce it as a new kind of term with its own reduction and typing rules. In fact we need a collection of Ys, one for each type. To improve readability we’ll call them fix. (T-Fix) (R-Fix) where x is not free in v Exercise: why is R-Fix like this, instead of ? And why are we only interested in fix at function types? Types and Programming Languages Lecture 7 - Simon Gay
Recursion in simply typed lambda calculus Example Given a recursive function definition: f(x:int) = if x==0 then 1 else x*f(x-1) we can rewrite it as a recursively-defined -abstraction: f = x:int.if x==0 then 1 else x*f(x-1) then abstract again on the function name: f:intint.x:int.if x==0 then 1 else x*f(x-1) this term has type (int int) (int int) and we use the appropriate fix to get the function: Types and Programming Languages Lecture 7 - Simon Gay
Naming The lambda calculus does not seem to give a direct way of expressing programs in the SFL style: a sequence of named function definitions followed by an expression. But we do have a way of associating a term with a name: -abstraction and function application. Given the program f(x:int):int = body-f g(x:int):int = body-g e we can construct -terms F and G corresponding to f and g, then form ((f:intint.g:intint.e)F)G so that f and g can be used within e, and F and G are only written once. Types and Programming Languages Lecture 7 - Simon Gay
Naming We prefer to work more directly with a programmer-friendly syntax. The idea is to write let f(x:int):int = body-f g(x:int):int = body-g in e end and we can define a typing rule for let: (T-Let) Semantically we regard let x = e in e’ as an abbreviation for (x:T.e’)e . Types and Programming Languages Lecture 7 - Simon Gay
Let and Multiple Definitions A let with several definitions can be regarded as an abbreviation: let f(x:int):int = body-f g(x:int):int = body-g in e end let f(x:int):int = body-f in let g(x:int):int = body-g in e end end Types and Programming Languages Lecture 7 - Simon Gay
Let and Recursive Definitions We want to allow let definitions to be recursive, intending that recursive function definitions will be translated into the equivalent of fix expressions. There’s a small issue: let allows us to define values as well as functions, but we don’t want to allow recursively-defined values (why not?) A convenient solution is to distinguish between value and function definitions by using the keywords val and fun. let fun f(x:int):int = body-f fun g(x:int):int = body-g val a:int = 1 in e end Types and Programming Languages Lecture 7 - Simon Gay
Simply Typed Lambda Calculus is Safe It is straightforward to prove type preservation and type safety theorems for the simply typed lambda calculus, in the same way as for the Simple Functional Language. The same is true when we add recursion (using fix). Exercise: prove type preservation and type safety theorems for the simply typed lambda calculus. Types and Programming Languages Lecture 7 - Simon Gay
A Better Functional Language Combining the ideas so far (function types, let for introducing names, fun and val to distinguish between function definitions (can be recursive) and value definitions (can’t be recursive)), introducing more convenient syntax for (fn x:T => e instead of x:T.e), and using = instead of is in function definitions, we get a BFL. BFL looks very much like a small subset of Standard ML. Multi-argument functions must be curried. An implementation of a typechecker for BFL can be found on the course web page, together with a commentary. Types and Programming Languages Lecture 7 - Simon Gay
Reading Pierce: 9; 12 (more challenging) for the proof of termination. Exercises Pierce: 9.2.1, 9.2.2, 9.2.3, 9.3.9, 9.3.10, 9.4.10 Types and Programming Languages Lecture 7 - Simon Gay