300 likes | 412 Views
This lecture material explores the role of intersection types within refinement type systems, particularly focusing on their compatibility with programming languages that incorporate effects. It addresses unsoundness issues in systems like ML, emphasizing how traditional intersection types fall short. The discussion includes the principles of subtyping, algorithmic rules, safety considerations, and the complexities involved in bidirectional type checking. The implications of polymorphism and the necessity of totality in function applications are also analyzed to present a comprehensive overview of intersection types in type theory.
E N D
Davies-Pfenning: Intersection Types and Effects Robert Harper Fall Semester, 2003
Intersection Types • Intersections are fundamental to refinement types:nat! pos Æ pos! ps • Conventional intersection types are incompatible with languages with effects. • Related to unsoundness in the original ML type system. 15-814 Type Refinements
Unsoundness • The classic ML mistake:let x : ‘a list ref = ref nil inlet y = (x := [true]) inlet z = hd(!x)+1 in z • Clearly unsound! But why? • nil has type ‘a list • so (?) ref nil has type ‘a list ref. • Boom. 15-814 Type Refinements
Substitution Principle • Let polymorphism in ML is justified by substitution: • But replication of ref nil allocates two cells, not one! 15-814 Type Refinements
Substitution Principle • Solution: ensure that CBV = CBN. • Replication or removal doesn’t change meaning. • Conservative approximation: the value restriction. • Require bound expression to be a syntactic value (constant, lambda, pair of values, etc). 15-814 Type Refinements
Substitution Principle • But, unfortunately, nil @ nil is not a value! • So it’s not polymorphic. • Annoying, especially interactively. • Valuability: • Every value is valuable. • Application of a total function to a valuable argument is valuable. • Requires a notion of totality. 15-814 Type Refinements
Unsoundness • A related problem:let x = ref (1) : nat ref Æ pos ref inlet y = (x := ) inlet z = !x in(z:pos) • The bit string 1 has type nat Æ pos. • So (?) ref(1) should be nat ref Æ pos ref. • But the value is , which is not pos! 15-814 Type Refinements
Substitution Principle • Typing rule for intersections replicates. • Must restrict subject to be a value (or valuable). • Elim “chooses” which version to use. 15-814 Type Refinements
Subtyping • Subtyping is least pre-order containing: • pos· nat, nat· bits • Co- and contra-variant function subtyping. • Intersections are meets (glb’s). • Ref’s are invariant: 15-814 Type Refinements
Non-distributivity • Do not have the principle • Consider x.ref(). • OK: unit! nat ref Æ unit! pos ref • Not OK: unit ! (nat ref Æ pos ref) 15-814 Type Refinements
Algorithmic Subtyping • Make transitivity and reflexivity admissible. • Related to confluence in term rewriting. • Precludes searching for arbitrary mediating type: A· B if 9 C A· C· B • Main changes: • No transitivity. • Axioms such as pos· bits. • Special treatment of meets. 15-814 Type Refinements
Algorithmic Subtyping • Key algorithmic rules for meets: • Upper bound is not an intersection. • Without loss of generality. • Forces search order to handle these first. 15-814 Type Refinements
Typing Rules • Judgement form: • Context governs locations. • Context governs variables. • Most rules are standard. 15-814 Type Refinements
Constructor Rules 15-814 Type Refinements
Constructor Rules 15-814 Type Refinements
Case Rules 15-814 Type Refinements
Case Rules 15-814 Type Refinements
Case Rules 15-814 Type Refinements
Intersection, Subsumption 15-814 Type Refinements
Safety • Without going into details, this version of the language is safe. • Define a state machine with a store. • Prove the usual progress and preservation theorems. • See the paper for details; nothing especially surprising. 15-814 Type Refinements
Bidirectional Type Checking • Non-goal oriented type synthesis is infeasible. • Generates more than you’d want to know. • e.g., nine clauses for the addition function. • No principal types, so no “best” answer. • Want some form of type inference. • Just impractical to specify everything. • No good way to specify intersection types. 15-814 Type Refinements
Bidirectional Type Checking • Distinguish synthesizable from checkable terms. • Synthesizable: can infer a type. • Checkable: can be tested against a type. • Add explicit “cast” (ascription) operation. • Specify type of an arbitrary expression. • No run-time overhead! 15-814 Type Refinements
Bidirectional Type Checking • Inferable terms: • Checkable terms: 15-814 Type Refinements
Bidirectional Typing • Synthesis: • Analysis: 15-814 Type Refinements
Bidirectional Typing • Analyzing ’s: • Synthesizing ascriptions: 15-814 Type Refinements
Bidirectional Typing • The inclusion of inferable into checkable is tricky. • Can only check a value against an intersection (for soundness). • Checking inferables requires distinguishing values from non-values. 15-814 Type Refinements
Bidirectional Typing 15-814 Type Refinements
Polymorphism • Essentially, treat as an infinite intersection. • 8 . A · {B/}A • A· B ¾ A·8 B, provided not free in A • No right-distributivity of 8 over !. • Rest goes through analogously. • Value-restricted polymorphism as in SML. 15-814 Type Refinements
Increment: val inc : (bits! bits)Æ (nat! pos) = fix inc. n. case n of) 1 j x0 ) x1 j x1) (inc x) 0 • Checker pushes declared type onto function to verify typing. 15-814 Type Refinements
Examples • Addition:val add : (nat ! nat ! nat) Æ (pos! nat! pos) Æ(nat! pos! pos) =fix plus m n . case m of) n | x 0 ) …plus… | x 1 ) …inc…plus… 15-814 Type Refinements