semantic casts
play

Semantic Casts: Contracts and Structural Subtyping in a Nominal - PowerPoint PPT Presentation

Semantic Casts: Contracts and Structural Subtyping in a Nominal World Robby Findler University of Chicago Matthew Flatt University of Utah Matthias Felleisen Northeastern University 1 Component marketplace - McIlroy's vision (1969) -


  1. Semantic Casts: Contracts and Structural Subtyping in a Nominal World Robby Findler University of Chicago Matthew Flatt University of Utah Matthias Felleisen Northeastern University 1

  2. Component marketplace - McIlroy's vision (1969) - Independent developers produce pieces of programs (components) - 3rd parties compose the components - Economic benefits: division of labor and competition - Software construction: merely plug & play 2

  3. 3

  4. 4

  5. 5

  6. 6

  7. 7

  8. 8

  9. 9

  10. 10

  11. What is a contract? - Agreement between two components - Only allows certain patterns of interactions 11

  12. Why check contracts? - Find faulty components - Accountability supports component economy 12

  13. Contracts [Beugnard et al. 1999] - Syntactic: types int f(int[] x, int k) - Semantic level 1: behavioral int f(int[] x, int k) // 0 <= k < x.length() - Semantic level 2: sequencing, concurrency finalize is called for all objects - Quality of service: space, time web server handles at least 1000 GET/sec 13

  14. Behavioral contract desiderata - Simplicity (dynamic enforcement) - Precise enforcement (no false pos/neg) - Blame 14

  15. Behavioral contract history - Parnas: 1972 - Luckham: ANNA for Ada - Meyer: Eiffel - ... 15

  16. Queues: an example 16

  17. Queue class Q implements IQueue { void enq(int X) {...} int deq() {...} boolean empty() {...} } 17

  18. Queue class Q implements IQueue { void enq(int X) {...} // @post !this.empty() int deq() {...} // @pre !this.empty() boolean empty() {...} } 18

  19. Queue class Q implements IQueue { void enq(int X) {...} // @post !this.empty() int deq() {...} // @pre !this.empty() boolean empty() {...} } Good client IQueue q = new Q(); q.enq(1); q.deq(); 19

  20. Queue class Q implements IQueue { void enq(int X) {...} // @post !this.empty() int deq() {...} // @pre !this.empty() boolean empty() {...} } Good client Bad client IQueue q = new Q(); IQueue q = new Q(); q.enq(1); q.deq(); q.deq(); q.enq(1); 20

  21. Queue class Q implements IQueue { void enq(int X) {...} // @post !this.empty() int deq() {...} // @pre !this.empty() boolean empty() {...} } Good client Bad client IQueue q = new Q(); IQueue q = new Q(); q.enq(1); q.deq(); q.deq(); q.enq(1); Blame q.deq(); in Bad Client 21

  22. Queue with observer class Q implements IQueue { Obs o; void enq(int X) {...} // @post !this.empty() // effect: o.onEnq(this) int deq() {...} // @pre !this.empty() // effect: o.onDeq(this) void register(Obs _o) {o = _o;} // please: a "good" Observer } 22

  23. Good observer class GoodO implements Obs { void init() {...} void onEnq(IQueue q) {...} // @post !q.empty() void onDeq(IQueue q) {...} } 23

  24. Good observer Bad Observer class GoodO class BadO implements Obs { implements Obs { void init() {...} void init() {...} void onEnq(IQueue q) void onEnq(IQueue q) {...} { q.deq() } // @post !q.empty() void onDeq(IQueue q) void onDeq(IQueue q) {...} {...} } } 24

  25. Client Queue BadO 25

  26. Client links BadO and Queue Client Queue BadO 26

  27. Queue post-condition failure Client Queue BadO 27

  28. Who to blame? Client Queue BadO 28

  29. Who to blame? Client Queue BadO - Client combines mis-matched components - BadO violates informal contract - Queue is blamed 29

  30. Queue with observer class Q implements IQueue { Obs o; void enq(int X) {...} // @post !this.empty() // effect: o.onEnq(this) int deq() {...} // @pre !this.empty() // effect: o.onDeq(this) void register(Obs _o) {o = _o;} // please: a "good" Observer } 30

  31. Queue with observer class Q implements IQueue { Obs o; void enq(int X) {...} // @post !this.empty() // effect: o.onEnq(this) int deq() {...} // @pre !this.empty() // effect: o.onDeq(this) void register(Obs _o) {o = _o;} @pre _o.onEnq(...) // } 31

  32. Contracts in interfaces? 32

  33. Observer contracts interface Obs { void init(); void onEnq(IQueue q); // @post !q.empty() void onDeq(IQueue q); // @pre !q.empty() } Force observers to meet pre- and post-conditions that Queue needs 33

  34. Controlling BadO class BadO implements Obs { void init() {...} void onEnq(IQueue q) { q.deq() } void onDeq(IQueue q) {...} } 34

  35. Controlling BadO class BadO implements Obs { void init() {...} void onEnq(IQueue q) { q.deq() } // @post !q.empty() void onDeq(IQueue q) {...} } 35

  36. A A' 36

  37. A A' 37

  38. A A' A - A' 38

  39. A A' A - A' 39

  40. Queue Class class Q implements IQueue { ... } Positive Queue interface IPosQ { void enq(int X) {...} // @pre X >= 0 // @post !this.empty() int deq() {...} // @pre !this.empty() // @post @ret >= 0 } 40

  41. Queue Class class Q implements IQueue { ... } Positive Queue interface IPosQ { void enq(int X) {...} // @pre X >= 0 // @post !this.empty() int deq() {...} // @pre !this.empty() // @post @ret >= 0 } 41

  42. Nominal subtyping Structural subtyping - Hierarchy explicit - Hierarchy implicit - Conventional OO PLs: - Research OO PLs: C++, C#, Eiffel, Java Moby, OML, OCaml, LOOM, PolyTOIL 42

  43. Nominal subtyping Structural subtyping - Simple to implement - Harder to implement - Simple type-error messages - Complex type-error messages - Inhibits re-use - Permits flexible re-use 43

  44. QClass class Q implements IQueue { ... } IQueue IPosQ interface IQueue { interface IPosQ { void enq(int X) {...} void enq(int X) {...} // @post !this.empty() // @pre X >= 0 // @post !this.empty() int deq() {...} int deq() {...} // @pre !this.empty() // @pre !this.empty() // @post @ret >= 0 } } 44

  45. Structural Subtyping in an Nominal World 45

  46. semanticCast (obj, I, <fromStr>, <toStr>) A structural subtype "cast" 46

  47. semanticCast (obj, I, <fromStr>, <toStr>) The object that gets casted, now has additional contracts 47

  48. semanticCast (obj, I, <fromStr>, <toStr>) The interface that describes the additional contracts 48

  49. semanticCast (obj, I, <fromStr>, <toStr>) The name of the component where the object is from; Responsible for post-conds 49

  50. semanticCast (obj, I, <fromStr>, <toStr>) The name of the component where the object is sent; Responsible for pre-conds 50

  51. semanticCast (obj, I, <fromStr>, <toStr>) Result ensures I's contracts but otherwise identical to obj Has type I, even if obj doesn't 51

  52. A A' A - A' 52

  53. A A' semanticCast (o,A, , ) A - A' 53

  54. A A' semanticCast semanticCast (o,A, , ) (o,A', , ) A - A' 54

  55. <Queue> <Client> IQueue q = new Q(); q.enq(1); q.deq(); q.enq(-1); <PosQueue> q 55

  56. <Queue> <Client> IQueue q = new Q(); q.enq(1); q.deq(); q.enq(-1); <PosQueue> q 56

  57. <Queue> <Client> IQueue q = new Q(); q.enq(1); q.deq(); q.enq(-1); semanticCast (q, semanticCast (q, IQueue, IPosQ, <Queue>, <PosQueue>, <PosQueue>) <Client>) <PosQueue> q 57

  58. <Queue> <Client> IQueue q = new Q(); q.enq(1); q.deq(); q.enq(-1); semanticCast (q, semanticCast (q, IQueue, IPosQ, <Queue>, <PosQueue>, <PosQueue>) <Client>) <PosQueue> q 58

  59. <Queue> <Client> IQueue q = new Q(); q.enq(1); q.deq(); q.enq(-1); semanticCast (q, semanticCast (q, IQueue, IPosQ, <Queue>, <PosQueue>, <PosQueue>) <Client>) <PosQueue> q 59

  60. <Queue> <Client> IQueue q = new Q(); q.enq(1); q.deq(); q.enq(-1); semanticCast (q, semanticCast (q, IQueue, IPosQ, <Queue>, <PosQueue>, <PosQueue>) <Client>) <PosQueue> q 60

  61. Semantics of semanticCast 61

  62. Semantics of semanticCast 62

  63. Semantics of semanticCast 63

  64. Semantics of semanticCast 64

  65. Semantics of semanticCast 65

  66. Semantics of semanticCast 66

  67. Semantics of semanticCast 67

  68. Semantics of semanticCast 68

  69. semanticCast (o, I, <from> , <to> ).m(o') = semanticCast (o.m( semanticCast o', J, <to> , <from> ), K, <from> , <to> ) interface I { K m(J x); } interface J { ... } interface K { ... } 69

  70. Implementation - Proxies - Construct new proxies at method calls 70

  71. Wrap up 71

  72. Structural subtyping for contracts - Adds flexibility to conventional languages - Contracts still simple boolean expressions - Proper blame assignment - If a tree in the forest hasn't yet fallen, it didn't make a sound 72

  73. Thank you. 73

Recommend


More recommend