1 / 37

Ownership Type Systems: Pedigree Types and Inference

This paper introduces a powerful static system called Pedigree Type Inference that incorporates ownership type systems with parameterized classes. It provides a simple and intuitive syntax for parametric polymorphism and demonstrates an example program in Pedigree Types.

deonf
Download Presentation

Ownership Type Systems: Pedigree Types and Inference

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. Pedigree Types Yu David Liu, Johns Hopkins University / SUNY Binghamton Scott F. Smith, Johns Hopkins University July 7, 2008 @ IWACO’08

  2. Ownership Type Systems Ownership with ParameterizedClasses Universe Types Simple and Intuitive Syntax Parametric Polymorphism Pedigree Types and Inference

  3. An Example Program in Pedigree Types(and in Universe Types) class Main { public static void main (String[] args) { View v1 = new View(); Controller c1 = new Controller(); } } class View { sibling Controller ctrl; View() { Button b1 = new child Button(ctrl, this); } void refresh() { … } } class Controller { … } class Button { … } * The two pedigrees above are identical to “peer” and “rep” in Universe Types.

  4. The Example in UML :Main v1:View c1:Contoller b1:Button * The top-down direction indicates ownership.

  5. The General Form of Pedigrees Good case: sibling = (parent)^1 (child)^1 Good case: child = (parent)^0 (child)^1 Bad case: nephew = (parent)^1 (child)^2 Bad case: grandchild = (parent)^0 (child)^2 Good case: self = (parent)^0 (child)^0 Good case: parent = (parent)^1 (child)^0 (parent)^a (child)^b where a>=0, b = 0 or 1

  6. class Main { public static void main (String[] args) { View v1 = new View(); Controller c1 = new Controller(); } } class View { sibling Controller ctrl; View() { Button b1 = new child Button(ctrl, this); } void refresh() { … } } class Controller { … } class Button { … }

  7. class Main { public static void main (String[] args) { View v1 = new View(); Controller c1 = new Controller(); } } class View { sibling Controller ctrl; View() { Button b1 = new child Button(ctrl, this); } void refresh() { … } } class Controller { … } class Button{ parent View container; Controller ctrl; Button(Contoller ctrl, View v) { this.ctrl = ctrl; this.container = v; } void refresh () { … container.refresh();} }

  8. Is (parent)^10 (child)^1 Useful ? “nai, nai!” thus spoke the inference algorithm. * “nai” means “yes” in Greek.

  9. class Main { public static void main (String[] args) { View v1 = new View(); Controller c1 = new Controller(); } } class View { sibling Controller ctrl; View() { Button b1 = new child Button(ctrl, this); } void refresh() { … } } class Controller { … } class Button{ parent View container; Controller ctrl; Button(Contoller ctrl, View v) { this.ctrl = ctrl; this.container = v; } void refresh () { … container.refresh();} }

  10. Options for the Omitted Pedigree • Treat it as “sibling”.

  11. Defaulting as “sibling” :Main v1:View c1:Contoller b1:Button c1 is an “uncle” of b1, not a “sibling”.

  12. Options for the Omitted Pedigree • Treat it as “sibling”. • Treat it as “world”, i.e. shared by everyone.

  13. Defaulting as “world” c1: Controller :Main c2: Controller s1:System s2:System v1:View c1: Controller v2:View c2: Controller b1:Button b2:Button The encapsulation of s1 and s2 is broken!

  14. Options for the Omitted Pedigree • Treat it as “sibling”. • Treat it as “world”, i.e. shared by everyone. • Treat it as some pedigree that can be reclaimed by dynamic casting (a “top type” pedigree).

  15. Options for the Omitted Pedigree • Treat it as “sibling”. • Treat it as “world”, i.e. shared by everyone. • Treat it as some pedigree that can be reclaimed by dynamic casting (a “top type” pedigree). • Treat it as some pedigree that can be inferred statically.

  16. Pedigree Types A constraint-based type system to embed heap objects onto the ownership tree reusing the vocabulary of human genealogy: • Declare a pedigree only if you care. • Given a reference with its pedigree omitted, it is equivalent to think of it having a pedigree of (parent)^a (child)^b, where a and b are type variables to be solved by the inference algorithm, where a ranges over non-negative integers and b ranges over {0, 1}. • A typechecked program means an ownership tree exists to embed heap objects. • A type error means an “incest”-free tree cannot be constructed.

  17. Pedigree Type Inference A powerful static system with the following features:

  18. Pedigree Type Inference A powerful static system with the following features: • It is parametrically polymorphic.

  19. The Need for Polymorphism :Main v1:View c1:Contoller b1:Button d: Dialog b2:Button

  20. Pedigree Type Inference A powerful static system with the following features: • It is parametrically polymorphic. • The technique: thinking about ML-style let-polymorphism in OO languages.

  21. class Main { public static void main (String[] args) { View v1 = new View(); Controller c1 = new Controller(); } } class View { sibling Controller ctrl; View() { Button b1 = new child Button(ctrl, this); } void refresh() { … } } class Controller { … } class Button{ parent View container; Controller ctrl; Button(Contoller ctrl, View v) { this.ctrl = ctrl; this.container = v; } void refresh () { … container.refresh();} }

  22. ∨ class Main { public static void main (String[] args) { View v1 = new View(); Controller c1 = new Controller(); } } class View { sibling Controller ctrl; View() { Button b1 = new child Button(ctrl, this); } void refresh() { … } } class Controller { … } class Button{ parent View container; (parent)^a1 (child)^b1 Controller ctrl; Button(Contoller ctrl, View v) { this.ctrl = ctrl; this.container = v; } void refresh () { … container.refresh();} } a1, b1

  23. Pedigree Type Inference A powerful static system with the following features: • It is parametrically polymorphic. • The technique: thinking about ML-style let-polymorphism in OO languages. • Indirect references are polymorphically treated as well.

  24. ∨ class Main { public static void main (String[] args) { View v1 = new View(); Controller c1 = new Controller(); } } class View { sibling Controller ctrl; View() { Button b1 = new child Button(ctrl, this); } void refresh() { … } } class Controller { … } class Button{ parent View container; (parent)^a1 (child)^b1 Controller ctrl; Button(Contoller ctrl, View v) { this.ctrl = ctrl; this.container = v; } void refresh () { … container.refresh();} } a1, b1

  25. ∨ class Main { public static void main (String[] args) { View v1 = new View(); Controller c1 = new Controller(); } } class View { sibling Controller ctrl; View() { Button b1 = new child Button(ctrl, this); } void refresh() { … } Timer t; } class Controller { … } class Button{ parent View container; (parent)^a1 (child)^b1 Controller ctrl; Button(Contoller ctrl, View v) { this.ctrl = ctrl; this.container = v; } void refresh () { … container.refresh();} } a1, b1

  26. ∨ class Main { public static void main (String[] args) { View v1 = new View(); Controller c1 = new Controller(); } } class View { sibling Controller ctrl; View() { Button b1 = new child Button(ctrl, this); } void refresh() { … } (parent)^a2 (child)^b2 Timer t; } class Controller { … } class Button{ parent View container; (parent)^a1 (child)^b1 Controller ctrl; Button(Contoller ctrl, View v) { this.ctrl = ctrl; this.container = v; } void refresh () { … container.refresh();} } a1, b1, a2, b2

  27. Pedigree Type Inference A powerful static system with the following features: • It is parametrically polymorphic. • It correctly handles mutually recursive classes.

  28. Pedigree Type Inference A powerful static system with the following features: • It is parametrically polymorphic. • It correctly handles mutually recursive classes. • It is inter-procedural.

  29. class Main { public static void main (String[] args) { View v1 = new View(); Controller c1 = new Controller(); } } class View { sibling Controller ctrl; View() { Button b1 = new child Button(ctrl, this); } void refresh() { … } } class Controller { … } class Button{ parent View container; Controller ctrl; Button(Contoller ctrl, View v) { this.ctrl = ctrl; this.container = v; } void refresh () { … container.refresh();} }

  30. Pedigree Type Inference A powerful static system with the following features: • It is parametrically polymorphic. • It correctly handles mutually recursive classes. • It is inter-procedural. • It allows for flexible structural subtyping with recursive object types.

  31. Pedigree Type Inference A powerful static system with the following features: • It is parametrically polymorphic. • It correctly handles mutually recursive classes. • It is inter-procedural. • It allows for flexible structural subtyping with recursive object types. • Standard object types are handled via μ- types [Amadio & Cardelli]. • Pedigree subsumption is also allowed: • self <: sibling • parent <: uncle • (parent)^a (child)^b <: (parent)^(a+1) (child)^(b+1)

  32. Pedigree Type Inference A powerful static system with the following features: • It is parametrically polymorphic. • It correctly handles mutually recursive classes. • It is inter-procedural. • It allows for flexible structural subtyping with recursive object types. • It is decidable: reduced to finding non-negative solutions to linear diophantine equations, a well-studied problem.

  33. Formal Results The type system is rigorously defined on top of a Java-like object model, with following properties formally proved: • The type system is sound (proved via subject reduction and progress). • Deep ownership preservation: any reference at run time has to point to an object with a pedigree (parent)^a (child)^b where a>=0 and b = 0 or 1. • Shape enforcement: if a reference is declared to have pedigree (parent)^a (child)^b, then at run time it points to an object with pedigree (parent)^a (child)^b, or a pedigree subsumed by it.

  34. Extensions We believe Pedigree Types can be extended with the following features (more discussions in the paper): • “owner-as-modifier” ownership tree: in our terms, it means to allow (parent)^a (child)^b where a>=0 and b>1, as long as the reference is read-only. • Selective exposure: allow programmer-defined policies for exceptional cases, like “allow access from my grandparent”. • Opt-out references. • Dynamic class loading.

  35. Related Work • Universe Types (UT) • Similarity in syntax: “peer” and “rep”. • UT features we do not have: “owner-as-modifiers”, generics, ownership transfer. • Our features: parametric polymorphism for omitted pedigrees; a more general form of pedigrees; static inference. • Ownership with Parameterized Classes • Similarity in expressiveness: parametric polymorphism. • Numerous extension features we do not cover (yet): effect encapsulation, interaction with concurrency, selective exposure, multiple ownership. • Our features: minimal declarations (declare only when you care!), polymorphic inference (sound, decidable, inter-procedural, consideration for realistic OO features such as recursive types and classes).

  36. Concluding Remarks • Programmability: very low-maintenance declaration system with minimal extension to the Java object model. • Expressiveness: on par with existing ownership systems using parameterized classes (additions: “self”, “parent”); a powerful inference algorithm. • Correctness: type soundness, ownership enforcement, shape enforcement. Future work: implementation, advanced features such as their impact on concurrency.

  37. Thank you!

More Related