<<

Homework Five Is Alive

Simply -Typed • Homework 5 has not been returned • Waiting on a few students who want to turn it in later • There will be no Number Six

#1 #2

Back to School Today’s Cunning Plan • What is operational semantics? When would • Overview you use contextual (small-step) semantics? • First-Order Type Systems • What is denotational semantics? • Typing Rules • What is axiomatic semantics? What is a • Typing Derivations verification condition? • Type Safety

#3 #4

Why Typed Languages? Why Not Typed Languages?

• Development • Static type checking imposes constraints on the – Type checking catches early many mistakes programmer – Reduced debugging time – Some valid programs might be rejected – Typed signatures are a powerful basis for design – But often they can be made well-typed easily – Typed signatures enable separate compilation – Hard to step outside the language (e.g. OO programming • Maintenance in a non-OO language, but cf. Ruby, OCaml, etc.) – Types act as checked specifications • Dynamic safety checks can be costly – Types can enforce abstraction – 50% is a possible cost of bounds-checking in a tight loop • Execution • In practice, the overall cost is much smaller – Memory management must be automatic ⇒ need a – Static checking reduces the need for dynamic checking garbage collector with the associated run-time costs – Safe languages are easier to analyze statically – Some applications are justified in using weakly-typed • the compiler can generate better code languages (e.g., by external safety proof) #5 #6

1 Properties of Type Systems Why Formal Type Systems?

• How do types differ from other program • Many typed languages have informal annotations descriptions of the type systems (e.g., in – Types are more precise than comments language reference manuals) – Types are more easily mechanizable than • A fair amount of careful analysis is required program specifications to avoid false claims of type safety • Expected properties of type systems: • A formal presentation of a type system is a – Types should be enforceable precise specification of the type checker – Types should be checkable algorithmically – And allows formal proofs of type safety – Typing rules should be transparent • But even informal knowledge of the • It should be easy to see why a program is not well- principles of type systems help typed #7 #8

Formalizing a Type System Typing Judgments

1. Syntax • Judgment (recall) • Of expressions (programs) – A statement J about certain formal entities • Of types – Has a truth value  J • Issues of binding and scoping – Has a derivation ⊢ J (= “a proof”) 2. Static semantics (typing rules) • A common form of typing judgment : • Define the typing judgment and its derivation rules Γ ⊢ e : τ (e is an expression and τ is a type) 3. Dynamic semantics (e.g., operational) • Γ (Gamma) is a set of type assignments for the free • Define the evaluation judgment and its derivation rules variables of e 4. Type soundness – Defined by the grammar Γ ::= | Γ, x : τ • Relates the static and dynamic semantics – Type assignments for variables not free in e are not • State and prove the soundness theorem relevant – e.g, x : int, y : int ⊢ x + y : int #9 #10

Typing rules Typing Derivations

• Typing rules are used to derive typing • A typing derivation is a derivation of a typing judgment (big surprise there …) judgments • Example:

• Examples:

• We say Γ ⊢ e : τ to mean there exists a derivation of this typing judgment (= “we can prove it”) • Type checking : given Γ, e and τ find a derivation • Type inference : given Γ and e, find τ and a derivation

#11 #12

2 Proving Type Soundness Upcoming Exciting Episodes

• A typing judgment is either true or false • We will give formal description of first-order type • Define what it means for a value to have a type systems (no type variables) v τ ∈ – types (simply typed λ-calculus) (e.g. 5 ∈ int and true ∈ bool ) – Simple types (integers and booleans) • Define what it means for an expression to have a type – Structured types (products and sums) e ∈| τ | iff ∀v. (e ⇓ v ⇒ v ∈ τ ) – Imperative types (references and exceptions) • Prove type soundness – Recursive types If ⊢ e : τ then e ∈ | τ | • The type systems of most common languages are or equivalently first-order If ⊢ e : τ and e ⇓ v then v ∈ τ • This implies safe execution (since the result of a • The we move to second-order type systems unsafe execution is not in τ for any τ) – Polymorphism and abstract types #13 #14

Simply-Typed Lambda Calculus Static Semantics of F 1

• Syntax: • The typing judgment Terms e ::= x | λx: τ. e | e e 1 2 Γ ⊢ e : τ | n | e 1 + e 2 | iszero e | true | false | not e • Some (simpler) typing rules: | if e 1 then e 2 else e 3 τ τ τ Types ::= int | bool | 1 → 2 τ τ • 1 → 2 is the • → associates to the right • Arguments have typing annotations

• This language is also called F1 #15 #16

More Static Semantics of F 1 Typing Derivation in F 1

• Consider the term λx : int. λb : bool. if b then f x else x – With the initial typing assignment f : int → int

Where Γ = f : int → int, x : int, b : bool

#17 #18

3 Type Checking in F 1 Operational Semantics of F 1

• Type checking is easy because • Judgment: – Typing rules are syntax directed e ⇓ v – Typing rules are compositional (what does this mean?) – All local variables are annotated with types • Values: v ::= n | true | false | λx: τ. e • In fact, type inference is also easy for F 1 • The evaluation rules … • Without type annotations an expression may have no unique type – Audience participation time: raise your hand and give me an evaluation rule. ⊢ λx. x : int → int ⊢ λx. x : bool → bool

#19 #20

Operational Semantics of F 1 Type Soundness for F (Cont.) 1 • Call-by-value evaluation rules (sample) • Theorem: If ⊢ e : τ and e ⇓ v then ⊢ v : τ – Also called, subject reduction theorem, type preservation theorem • This is one of the most important sorts of theorems in PL • Whenever you make up a new safe language you are expected to prove this Evaluation is – Examples: Vault, TAL, CCured, … undefined for ill- typed programs !

#21 #22

How Can We Prove It? Proof Approaches To Type Safety • Theorem: If ⊢ e : τ and e ⇓ v then ⊢ v : τ • Theorem: If ⊢ e : τ and e ⇓ v then ⊢ v : τ • Try to prove by induction on e

– Won’t work because [v 2/x]e’1 in the evaluation of e 1 e2 – Same problem with induction on ⊢ e : τ • Try to prove by induction on τ

– Won’t work because e 1 has a “bigger” type than e 1 e2 • Try to prove by induction on e ⇓ v

– To address the issue of [v 2/x]e’1 – This is it!

#23 #24

4 Type Soundness Proof Significance of Type Soundness

• Consider the case • The theorem says that the result of an evaluation has the same type as the initial expression • The theorem does not say that – The evaluation never gets stuck (e.g., trying to apply a non-function, to add non-integers, etc.), nor that – The evaluation terminates

⇓⇓⇓ τ τ • Even though both of the above facts are true of F 1 • From IH on e 1 … we have , x : 2 ⊢⊢⊢ e1’ : ⇓⇓⇓ τ • We need a small-step semantics to prove that the • From IH on e 2 … we have ⊢⊢⊢ v2 : 2 τ execution never gets stuck • Need to infer that ⊢⊢⊢ [v 2/x]e 1’ : and use the IH – We need a substitution lemma (by induction on e 1’) • I Assert: the execution always terminates in F 1 – When does the lambda calculus ever not terminate? #25 #26

Small-Step Contextual Semantics Decomposition Lemmas for F 1 for F 1 • We define redexes 1. If ⊢ e : τ and e is not a (final) value then there λ τ exist (unique) H and r such that e = H[r] r ::= n 1 + n 2 | if b then e 1 else e 2 | ( x: .e 1) v 2 • and contexts – any well typed expression can be decomposed – any well-typed non-value can make progress H ::= H 1 + e 2 | n 1 + H 2 | if H then e 1 else e 2 | H 1 e2 | τ τ (λx: τ. e ) H 2. Furthermore, there exists ’ such that ⊢ r : ’ 1 2 – the redex is closed and well typed • and local reduction rules 3. Furthermore, there exists e’ such that r → e’ and n1 + n 2 → n1 plus n 2 ⊢ e’ : τ’ if true then e 1 else e 2 → e1 – local reduction is type preserving if false then e 1 else e 2 → e2 4. Furthermore, for any e’, ⊢ e’ : τ’ implies ⊢ λ τ ( x: . e 1) v 2 → [v 2/x]e 1 H[e’] : τ • and one global reduction rule – the expression preserves its type if we replace the redex with an expression of same type H[r] → H[e] iff r → e #27 #28

Type Safety of F 1 What’s Next?

• Type preservation theorem • We’ve got the basic simply-typed – If ⊢ e : τ and e → e’ then ⊢ e’ : τ monomorphic lambda calculus – Follows from the decomposition lemma • Progress theorem • Now let’s make it more complicated … – If ⊢ e : τ and e is not a value then there exists e’ such • By adding features! that e can make progress: e → e’ • Progress theorem says that execution can make progress on a well typed expression • From type preservation we know the execution of well typed expressions never gets stuck – This is a (very!) common way to state and prove type safety of a language

#29 #30

5 Product Types: Dynamic Product Types: Static Semantics Semantics and Soundness

• Extend the syntax with (binary) tuples • New form of values: v ::= ... | (v 1, v 2)

e ::= ... | (e 1, e 2) | fst e | snd e • New (big step) evaluation rules: τ τ τ ::= ... | 1 × 2 × – This language is sometimes called F 1 • Same typing judgment Γ ⊢ e : τ

• New contexts: H ::= ... | (H 1, e 2) | (v 1, H 2) | fst H | snd H • New redexes:

fst (v 1, v 2) → v1

snd (v 1, v 2) → v2 • Type soundness holds just as before #31 #32

General PL Feature Plan Homework

• The general plan for language feature design • Read Wright and Felleisen article • You invent a new feature (tuples) • Work on your projects! • You add it to the lambda calculus – Status Update Due: Thursday Mar 23 • You invent typing rules and opsem rules • You extend the basic proof of type safety • You declare moral victory, and milling throngs of cheering admirers wait to carry you on their shoulders to be knighted by the Queen, etc.

#33 #34

6