1 / 71

Singleton Kinds

Singleton Kinds. Derek Dreyer Fall Semester, 2002. Part 1: Motivation. Type-Directed Compilation. Retain types throughout compilation using typed intermediate languages . Enables type-based optimizations Typechecking after compiler phases improves robustness of compiler

suzette
Download Presentation

Singleton Kinds

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Singleton Kinds Derek Dreyer Fall Semester, 2002

  2. Part 1:Motivation

  3. Type-Directed Compilation • Retain types throughout compilation using typed intermediate languages. • Enables type-based optimizations • Typechecking after compiler phases improves robustness of compiler • Makes it possible to target typed assembly language

  4. The TIL Compiler • Type-directed compiler for Core ML (Tarditi et al., PLDI 96) • Highly optimized • Intensional type analysis (Harper and Morrisett, POPL 95) • Other traditional optimizations, not previously implemented for functional languages (Tarditi’s thesis, 97)

  5. Problems with TIL • Large type representations • Whole-program optimizations • Doesn’t support modules!

  6. TILT (TIL Two) • Complete re-engineering of TIL • Compiles full Standard ML • Supports separate compilation • Sharing of type representations via singleton kinds.

  7. Structure of TILT Standard ML Elaboration High-level Intermediate Language HIL Phase-Splitting Mid-level Intermediate Language MIL Optimizations Code Generation

  8. HIL • Described in Harper-Stone 98, along with the elaboration algorithm • Based on Harper-Lillibridge (HL) formalism, restricted to second-class modules • Coercive signature subtyping (e.g. dropping components) handled by elaboration • HIL subtyping (like HL’s) strictly about forgetting of type identity

  9. Phase-Splitting • Erase sealing • Sealing just restricts the use of a module • Unnecessary after elaboration/typechecking • Split modules and signatures into two parts: • The static part has the type components • The dynamic part has the term components • Once separated, both parts can be written in the MIL.

  10. Phase-Splitting • X : sig type t val x : t end • X_Static : sig type t end • X_Dynamic : sig val x : X_Static.t end

  11. MIL Syntactic Classes • X_Static is a type constructor, which is classified by a kind. • X_Dynamic is a term, which is classified by a type.

  12. Simple Kinds • Base kind is T, the kind of types. • int : T, bool : T • Function and product kinds: • K1! K2, K1£ K2 • Example: • type (a,b) pair = a * b • pair = l(g:T £ T). p1g * p2g • pair : (T £ T) ! T

  13. Type Definitions • X : sig type t type u = A (* where A is big *) val x : t end • X_Static : T (* just the “t” component *) • X_Dynamic : t [A / u, X.Static / t]

  14. Dependent & Singleton Kinds(Stone and Harper, POPL 00) • To avoid space blowup, introduce • new singleton kind S(A) • B : S(A)  B ´ A : T • S(A) 6 T • Must also generalize ! and £ to: • Dependent function kind : Pa:K1.K2 • Dependent sum kind : Sa:K1.K2

  15. Dependent S Example • X_Static : S t:T.S(A) • X_Dynamic : t [p1(X_Static) / t, p2(X_Static) / u] • We haven’t lost any equivalences: p2(X_Static) ´ A[p1(X_Static) / t]

  16. Dependent P Example • F : funsig (X:sig type elem end) -> sig type elem = X.elem type set ... end • F_Static : Pa : T. (S(a) £ T)

  17. Advantages of Singletons • Carry advantages of translucency over to the MIL level: • Precise control of type propagation • Sharing of type representations • Clean handling of open-scope type definitions.

  18. Part 2:Type System

  19. Syntax • A ::= a | la:K.A | A1 A2 | <a=A1,A2> | p1A | p2A • K ::= T | Pa:K1.K2 | Sa:K1.K2 | S(A) • G ::= ² | G, a:K

  20. Typing Rules • Standard dependent typing rules:

  21. Selfification • Recall the idea of selfification from the translucent sums formalism: • If X : sig type t end, then X : sig type t = X.t end.

  22. Selfification • Recall the idea of selfification from the translucent sums formalism: • If X : sig type t end, then X : sig type t = X.t end. • Selfification arises naturally here as singleton introduction:

  23. Everything is Determinate • Unlike Harper-Lillibridge, there is no “value restriction” here on what can be selfified. • Every type constructor A is determinate because the language is pure and there is no sealing.

  24. Higher-Order Selfification • If X : sig structure A : SIGA structure B : SIGB end,then X : sig structure A : Selfify(SIGA, X.A) structure B : Selfify(SIGB, X.B) end

  25. Higher-Order Selfification • If X : sig structure A : SIGA structure B : SIGB end,then X : sig structure A : Selfify(SIGA, X.A) structure B : Selfify(SIGB, X.B) end • Achieved in type theory by a “kind strengthening” rule:

  26. Higher-Order Selfification • If F : funsig (X:SIGA) ! SIGB,then F : funsig (X:SIGA) ! Selfify(SIGB, F(X)) • Wait a sec! Can we do that?What about the “generativity” of F? • Well...the types in the body of F can’t really depend on run-time conditions.

  27. Higher-Order Selfification • Type constructors clearly can be selfified: • list : T ! T • Principal kind of list is Pa:T.S(list a)

  28. Higher-Order Selfification • Type constructors clearly can be selfified: • list : T ! T • Principal kind of list is Pa:T.S(list a) • And now for the kind strengthening rule: • Left premise necessary to ensure a not in the free variables of A

  29. Subkinding • Subkinding very similar to signature subtyping in Harper-Lillibridge:

  30. Question • So now that we’ve defined the typing judgment, onto equivalence. • But wait: if A ´ B : T, then how do we prove A : S(B)?

  31. Answer • So now that we’ve defined the typing judgment, onto equivalence. • But wait: if A ´ B : T, then how do we prove A : S(B)? • Answer: • A : S(A), and if A ´ B, then S(A) 6 S(B), so by subsumption A : S(B).

  32. Type Constructor Equivalence • Standard structural rules • Reflexive, symmetric, transitive • Beta-equivalence rules • Subsumption rule • Singleton elimination rule:

  33. Extensionality • Eta-equivalence provided in the form of extensionality rules:

  34. Admissibility of Eta • If F : Pa:K1.K2, then assuming a:K1,we have (la:K1.F(a))(a) ´ F(a) : K2,so by extensionality, (la:K1.F(a)) ´ F. • Cool property of extensionality: • Self rules are just reflexive forms of equivalence rules (nice for proofs later on • Can think of self rules as follows:

  35. Higher-Order Singletons • S(A) only valid if A : T. • In fact, S(A : K) at higher K is definable so that the singleton rules hold at any kind: • If A : S(B : K) and B : K, then A ´ B : S(B : K). • If A : K, then A : S(A : K) and S(A : K) 6 K. • If A1´ A2 : K1 and K16 K2,then S(A1 : K1) 6 S(A2 : K2).

  36. Higher-Order Singletons • Extensionality important here! • S(A : K) classifies constructors that are extensionally equal to the eta-expansion of A.

  37. Admissibility of Beta • It turns out that beta-equivalence is admissible in the presence of higher-order singletons:

  38. Subtleties of Equivalence • Constructor equivalence obviously depends on the context: • a:T, b:T `a´b : T. • a:T, b:S(a) `a´b : T.

  39. Subtleties of Equivalence • It less obviously depends on the kind at which the constructors are compared. • `la:T.a´la:T.int : T ! T. • `la:T.a´la:T.int : S(int) ! T. • This turns out to have a profound effect on the type equivalence algorithm.

  40. Part 3:Decidability of Typechecking

  41. Typechecking Algorithm • Want to determine if G` A : K • First synthesize principal kind KP of A • Then check if G` KP6 K

  42. Principal Kind Synthesis • G` A * K synthesizes principal K of A • Synthesis for intro and elim forms corresponds precisely to typing rules • For variables, we selfify: • G`a* S(a : G(a)) • Theorem: If G` A : K, then G` A * KP and G` KP6 K.

  43. Question • How do we prove theorem for self rule?

  44. Answer • How do we prove theorem for self rule? • Answer: Need to generalize theorem: • If G` A : K, then G` A * KP and G` KP6 S(A : K). (Lemma 2.2 in Stone-Harper)

  45. Subkinding • Subkinding is syntax-directed • To decide S(A) 6 S(B), we need to decide whether A ´ B : T • Decidability of typechecking reduces to decidability of constructor equivalence

  46. Equivalence Algorithm • Typically, to decide whether A ´ B, we “normalize-and-compare” • Define some reduction relation that is confluent and strongly normalizing • Then A ´ B iff their normal forms are equal • Doesn’t work when equivalence is kind- and context-dependent • e.g. la:T.a´la:T.int : S(int) ! T

  47. Equivalence Algorithm • Inspired by [Coquand 91] to define equivalence algorithm directly • Algorithmic judgment: G` A1, A2 : K • Big picture: • Constructor equivalence reduces to type equivalence (i.e. G` A1, A2 : T) • At kind T, reduce A1 and A2 to paths p1 and p2, expanding out singletons along the way • Compare p1 and p2 structurally

  48. Reducing to Type Equivalence • When checking G` A1, A2 : K, we can assume that G` A1 : K and G` A2 : K • If K is a singleton S(A), we can immediately accept because A1´ A and A2´ A, so:

  49. Reducing to Type Equivalence • At higher kind, algorithmic equivalence is precisely extensional equivalence: • Note that the kinds are “smaller” in the premises than in the conclusions.

  50. Reducing to Type Equivalence • At base kind T, we reduce A1 and A2 to a form in which we can structurally compare them, namely path form, also called weak head normal form: • Note: we could have done the singleton case this way as well.

More Related