Presentation is loading. Please wait.

Presentation is loading. Please wait.

Implementing a Dependently Typed λ -Calculus Ali Assaf Abbie Desrosiers Alexandre Tomberg.

Similar presentations


Presentation on theme: "Implementing a Dependently Typed λ -Calculus Ali Assaf Abbie Desrosiers Alexandre Tomberg."— Presentation transcript:

1 Implementing a Dependently Typed λ -Calculus Ali Assaf Abbie Desrosiers Alexandre Tomberg

2 Outline λ-calculus. Implementation strategies Typed λ-calculus Polymorphic types, System F Dependent types Current work

3 Motivations λ-calculus expresses function abstractions ◦ Powerful, Turing-complete. ◦ Foundation of functional programming languages. ◦ Strong connection with logic. This project: ◦ Study types ◦ Explore different implementations

4 The λ-calculus Very simple language: ◦ Terms M = x | λ x. M | M N ◦ Reductions (λ x. M) N => [N/x] M Examples ◦ Identity: λ x. x ◦ Constant function: λ x. λ y. x ◦ Omega: λ x. (x x)

5 Implementation strategies Explicit substitution ◦ term = var “x” | lam “x” M | app M N ◦ “Natural way” of representing lambda expressions. ◦ Problems :  No immediate α-renaming  Free variable capture problem

6 Implementation strategies (cont’d) De Bruijn indices ◦ term M = Var n | lam M | app M N ◦ e.g. Identity: λ. 1, Constant: λ. λ. 2 ◦ Advantages:  Unique representation ◦ Problems:  Not simple to manipulate. λ x. ( λ y. x) x = λ. (λ. 2). 1  Need to shift indices in substitution to avoid capture.

7 Implementation strategies (cont’d) Higher Order Abstract Syntax (HOAS) ◦ Use the features of the meta-language ! ◦ term M = lam f | app M N where f is a function term → term ◦ Term substitution : sub (lam f) N => lam (f N) ◦ α-renaming already provided! ◦ WARNING : Leads to ridiculously short implementations.

8 Our implementations De Bruijn in SML datatype exp = var of int | lam of exp | app of exp * exp fun shift (var x) l b = if x > b then var (x + l) else var x | shift (lam m) l b = lam (shift m l (b + 1)) | shift (app (m, n)) l b = app(shift m l b, shift n l b) fun sub (var y) s x l = if y = x then shift s l 0 (* Substitution *) else if y > x then var (y-1) (* Free variable *) else var y (* Bound variable *) | sub (lam m) s x l = lam (sub m s (x + 1) (l + 1)) | sub (app (m, n)) s x l = app (sub m s x l, sub n s x l) fun eval (var x) = var x | eval (lam m) = lam (eval m) | eval (app (m, n)) = case eval m of lam m' => eval (sub m' n 1 0) | m' => (app (m', eval n)) HOAS in SML datatype exp = lam of (exp -> exp) | app of exp * exp; fun eval (lam m) = lam (fn x => eval (m x)) | eval (app (m, n)) = case eval m of lam m' => eval (m' n) | m' => app (m', n)

9 Our implementations Twelf exp : type. lam : (exp -> exp) -> exp. app : exp -> exp -> exp. eval : exp -> exp -> type. eval/lam : eval (lam M) (lam M). eval/app : eval (app M N) N' <- eval M (lam M') <- eval (M' N) N'. SML datatype exp = lam of (exp -> exp) | app of exp * exp; fun eval (lam m) = lam (fn x => eval (m x)) | eval (app (m, n)) = case eval m of lam m' => eval (m' n) | m' => app (m', n)

10 The ω problem Consider the function: ω = λ x. ( x x ) What happens if we apply it to itself? ω ω = (λ x. ( x x )) ω => ω ω => ω ω =>... Evaluation never terminates! We say (ω ω) doesn’t have a normal form. To solve this problem, we introduce types.

11 Types Each function f has a fixed domain A and co-domain B (like sets in math). types τ = a | τ → σ where a is a base type (e.g. nat) Typing rules ◦ XXXXXXXXXXXXXX

12 Return of the ω What happens to ω ? ◦ ω = λ x. xx ω : α → β x : α, but also x : α → β α ≠ α → β ω cannot have a valid type! Simply-typed lambda calculus is strongly normalizing.

13 Implementing types Much easier in Twelf: use HOAS. This corresponds to Curry style. t : type. a : t. arrow : t -> t -> t. %infix right 10 arrow. exp : type. lam : (exp -> exp) -> exp. app : exp -> exp -> exp. check : exp -> t -> type. check/lam : check (lam M) (A arrow B) check (M x) B). check/app : check (app M N) B <- check M (A arrow B) <- check N A.

14 Examples Type checking: ◦ check (lam ([x] x)) (A arrow A) Secret weapon: we can use Twelf to do type inference ! ◦ %query 1 * check (lam ([x] x)) T  T = X1 arrow X2 arrow X1. ω ? ◦ %query 1 * check (lam ([x] app x x)) T  Query error -- wrong number of solutions: expected 1 in * tries, but found 0

15 Another implementation Cute trick : Then ill-typed terms cannot even be constructed ! This corresponds to Church style. t : type. a : t. arrow : t -> t -> t. %infix right 10 arrow. exp : t -> type. lam : (exp T1 -> exp T2) -> exp (T1 arrow T2). app : exp (T1 arrow T2) -> exp T1 -> exp T2.

16 Limitations of simple types Decidable, but no longer Turing complete. id = λ x : a. x id = λ x : b. x id = λ x : nat. x id = λ x : (a → a). x We need to write a different identity function for each type. ◦ To avoid that we need polymorphism.

17 Polymorphism: System F Idea: Allow abstraction over types. Then, we can write a single identity function for any type a: Λ a. λ x : a. x We extend our definition of types and terms: ◦ τ = a | τ → τ | Π a. τ ◦ M = x | λ x : τ. M | M N | Λ a. M | M {τ} Implementations follow the same idea.

18 Dependent types : LF Idea: Let types depend on values. Keep information about our types. Examples: ◦ Vector : Nat → type. ◦ Vector n is the type of vectors of length n. ◦ Exp t Advantages: ◦ We won’t need to prove properties about our programs !

19 Current work Polymorphic types in Twelf Dependent types in Twelf Types in SML ◦ Problems with HOAS.

20 Problems with HOAS Current functional languages (like SML) present a few problems: ◦ Do not allow us to look inside functions. ◦ Hard to generate λ terms. Solutions: ◦ Improve functional programming languages.  Beluga ◦ Try different paradigms.  Python

21 Why Python? Dynamically typed. Very flexible code generation. User-friendly interface. I = Lam(lambda x : x) K = Lam(lambda x : Lam (lambda y : x)) O = Lam(lambda x : App(x, x)) print "I = ", I print "K = ", K print "O = ", O >>> I = Lam u. (u) K = Lam w. (Lam v. (w)) O = Lam y. ((y)(y))

22 Conclusions and future work Many type systems. Various implementations. Besides implementing, our goals include: ◦ Proving equivalence of representations.


Download ppt "Implementing a Dependently Typed λ -Calculus Ali Assaf Abbie Desrosiers Alexandre Tomberg."

Similar presentations


Ads by Google