Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A hammer you can only hold by the handle

A hammer you can only hold by the handle

Presented at RustFest Zürich (http://zurich.rustfest.eu)

Rust’s type system provides tools to ensure safe memory management, and safe concurrent access to data. What if we used those same tools to encode and enforce other API constraints?

We can leverage affine types (non-Clone structs) to enforce that a user performs a series of operations in a certain order; or we can use structs as tokens representing the user’s ability to perform certain actions. And everything’s checked at compile time.

We’ll see how these techniques let us encode complex API constraints, and make them self-documenting by preventing disallowed behaviour at compile time.

Andrea Lattuada

September 30, 2017
Tweet

More Decks by Andrea Lattuada

Other Decks in Programming

Transcript

  1. A HAMMER YOU CAN ONLY
 HOLD BY THE HANDLE ANDREA

    LATTUADA @UTAAL
 SYSTEMS GROUP, DEPT. OF COMPUTER SCIENCE
 ETH ZÜRICH
  2. API

  3. API

  4. API

  5. API

  6. API

  7. API

  8. API

  9. API

  10. API

  11. API

  12. API

  13. OWNERSHIP (LINEAR / AFFINE TYPES) fn use_name(name: String) { }

    fn main() { let name = String::from(“Andrea”); use_name(name); println!("{}", name); }
  14. OWNERSHIP (LINEAR / AFFINE TYPES) fn use_name(name: String) { }

    fn main() { let name = String::from(“Andrea”); use_name(name); println!("{}", name); } error[E0382]: use of moved value: `name` ---- value moved here ^^^^ value used here after move
  15. OWNERSHIP (LINEAR / AFFINE TYPES) fn use_name(name: String) { }

    fn main() { let name = String::from(“Andrea”); use_name(name); println!("{}", name); } error[E0382]: use of moved value: `name` ---- value moved here ^^^^ value used here after move
  16. OWNERSHIP (LINEAR / AFFINE TYPES) fn use_name(name: String) { }

    fn main() { let name = String::from(“Andrea”); use_name(name); println!("{}", name); } error[E0382]: use of moved value: `name` ---- value moved here ^^^^ value used here after move
  17. OWNERSHIP (LINEAR / AFFINE TYPES) fn use_name(name: String) { }

    fn main() { let name = String::from(“Andrea”); use_name(name); println!("{}", name); } error[E0382]: use of moved value: `name` ---- value moved here ^^^^ value used here after move
  18. DROP fn main() { let a = get_number(); if a

    > 3 { let data = vec![3, 4, 8]; } println!("{}", data); }
  19. DROP fn main() { let a = get_number(); if a

    > 3 { let data = vec![3, 4, 8]; } println!("{}", data); } `data` dropped here
  20. #[derive(Clone)] pub struct Letter { text: String, } pub struct

    Envelope { letter: Option<Letter>, } pub struct PickupLorryHandle { done: bool, // references to lorry's resources }
  21. #[derive(Clone)] pub struct Letter { text: String, } pub struct

    Envelope { letter: Option<Letter>, } pub struct PickupLorryHandle { done: bool, // references to lorry's resources }
  22. #[derive(Clone)] pub struct Letter { text: String, } pub struct

    Envelope { letter: Option<Letter>, } pub struct PickupLorryHandle { done: bool, // references to lorry's resources }
  23. #[derive(Clone)] pub struct Letter { text: String, } pub struct

    Envelope { letter: Option<Letter>, } pub struct PickupLorryHandle { done: bool, // references to lorry's resources }
  24. #[derive(Clone)] pub struct Letter { text: String, } impl Letter

    { pub fn new(text: String) -> Self { Letter { text: text } } }
  25. pub struct Envelope { letter: Option<Letter>, } impl Envelope {

    pub fn wrap(&mut self, letter: &Letter) { self.letter = Some(letter.clone()); } } pub fn buy_prestamped_envelope() -> Envelope { Envelope { letter: None } }
  26. pub struct Envelope { letter: Option<Letter>, } impl Envelope {

    pub fn wrap(&mut self, letter: &Letter) { self.letter = Some(letter.clone()); } } pub fn buy_prestamped_envelope() -> Envelope { Envelope { letter: None } }
  27. pub struct Envelope { letter: Option<Letter>, } impl Envelope {

    pub fn wrap(&mut self, letter: &Letter) { self.letter = Some(letter.clone()); } } pub fn buy_prestamped_envelope() -> Envelope { Envelope { letter: None } }
  28. pub struct PickupLorryHandle { done: bool, // references to lorry's

    resources } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: &Envelope) { /* give letter */ } pub fn done(&mut self) { self.done = true; println!("sent"); } } pub fn order_pickup() -> PickupLorryHandle { PickupLorryHandle { done: false, /* other handles */ } }
  29. pub struct PickupLorryHandle { done: bool, // references to lorry's

    resources } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: &Envelope) { /* give letter */ } pub fn done(&mut self) { self.done = true; println!("sent"); } } pub fn order_pickup() -> PickupLorryHandle { PickupLorryHandle { done: false, /* other handles */ } }
  30. pub struct PickupLorryHandle { done: bool, // references to lorry's

    resources } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: &Envelope) { /* give letter */ } pub fn done(&mut self) { self.done = true; println!("sent"); } } pub fn order_pickup() -> PickupLorryHandle { PickupLorryHandle { done: false, /* other handles */ } }
  31. pub struct PickupLorryHandle { done: bool, // references to lorry's

    resources } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: &Envelope) { /* give letter */ } pub fn done(&mut self) { self.done = true; println!("sent"); } } pub fn order_pickup() -> PickupLorryHandle { PickupLorryHandle { done: false, /* other handles */ } }
  32. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); }
  33. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); }
  34. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); }
  35. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); }
  36. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); }
  37. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); }
  38. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); }
  39. 1.

  40. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(&rustfest_letter); lorry.pickup(&e); } lorry.done(); }
  41. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(&rustfest_letter); lorry.pickup(&e); } lorry.done(); }
  42. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(&rustfest_letter); lorry.pickup(&e); } lorry.done(); }
  43. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(&rustfest_letter); lorry.pickup(&e); } lorry.done(); }
  44. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(&rustfest_letter); lorry.pickup(&e); } lorry.done(); }
  45. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(&rustfest_letter); lorry.pickup(&e); } lorry.done(); } #[derive(Clone)] pub struct Letter { text: String, }
  46. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); #[derive(Clone)] pub struct Letter { text: String, } impl Envelope { pub fn wrap(&mut self, letter: Letter) { self.letter = Some(letter); } }
  47. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); #[derive(Clone)] pub struct Letter { text: String, } impl Envelope { pub fn wrap(&mut self, letter: Letter) { self.letter = Some(letter); } }
  48. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); #[derive(Clone)] pub struct Letter { text: String, } impl Envelope { pub fn wrap(&mut self, letter: Letter) { self.letter = Some(letter); } }
  49. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); #[derive(Clone)] pub struct Letter { text: String, } impl Envelope { pub fn wrap(&mut self, letter: Letter) { self.letter = Some(letter); } }
  50. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); #[derive(Clone)] pub struct Letter { text: String, } impl Envelope { pub fn wrap(&mut self, letter: Letter) { self.letter = Some(letter); } }
  51. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); #[derive(Clone)] pub struct Letter { text: String, } impl Envelope { pub fn wrap(&mut self, letter: Letter) { self.letter = Some(letter); } }
  52. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); } lorry.done(); }
  53. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut

    envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); } lorry.done(); } error[E0382]: use of moved value: `rustfest_letter` ^^^^^^^^^^^^^^^ value moved here in previous iteration
 of loop
  54. 1.

  55. 2.

  56. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup();
  57. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup();
  58. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup();
  59. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup();
  60. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); impl Envelope { pub fn wrap(&mut self, letter: &Letter) { self.letter = Some(letter.clone()); } }
  61. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); impl Envelope { pub fn wrap(&mut self, letter: &Letter) { self.letter = Some(letter.clone()); } } assert!(self.letter.is_none());
  62. // in a separate module fn main() { let rustfest_letter

    = Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); impl Envelope { pub fn wrap(&mut self, letter: &Letter) { self.letter = Some(letter.clone()); } } panic assert!(self.letter.is_none());
  63. pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:

    Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } }
  64. pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:

    Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } }
  65. pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:

    Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } }
  66. pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:

    Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } }
  67. pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:

    Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } }
  68. pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:

    Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } }
  69. pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:

    Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } }
  70. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(envelope); lorry.done(); }
  71. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(envelope); lorry.done(); }
  72. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(envelope); lorry.done(); }
  73. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(envelope); lorry.done(); }
  74. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(envelope); lorry.done(); }
  75. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(envelope); lorry.done(); } error[E0308]: mismatched types = note: expected type `ClosedEnvelope` found type `EmptyEnvelope` = help: here are some functions which might fulfill your needs: - .wrap(...) ^^^^^^^^ expected struct `ClosedEnvelope`, found struct `EmptyEnvelope`
  76. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); let closed_envelope = envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); lorry.done(); }
  77. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); let closed_envelope = envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); lorry.done(); }
  78. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); let closed_envelope = envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); lorry.done(); }
  79. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); let closed_envelope = envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); lorry.done(); }
  80. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); let closed_envelope = envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); lorry.done(); } error[E0382]: use of moved value: `envelope` -------- value moved here ^^^^^^^^ value used here after move
  81. 2.

  82. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); }
  83. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); }
  84. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); }
  85. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); }
  86. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); } impl Drop for PickupLorryHandle { fn drop(&mut self) { println!("sent"); } } impl PickupLorryHandle { pub fn done(self) { } …
  87. fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope

    = buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); } `lorry` dropped here impl Drop for PickupLorryHandle { fn drop(&mut self) { println!("sent"); } } impl PickupLorryHandle { pub fn done(self) { } …
  88. pub struct HttpResponseWritingHeaders { /* connection, … */ } pub

    struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ }
  89. pub struct HttpResponseWritingHeaders { /* connection, … */ } pub

    struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ }
  90. pub struct HttpResponseWritingHeaders { /* connection, … */ } pub

    struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ }
  91. pub struct HttpResponseWritingHeaders { /* connection, … */ } pub

    struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ }
  92. pub struct HttpResponseWritingHeaders { /* connection, … */ } pub

    struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ }
  93. pub struct HttpResponseWritingHeaders { /* connection, … */ } pub

    struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ }
  94. pub struct HttpResponseWritingHeaders { /* connection, … */ } pub

    struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ }
  95. pub struct HttpResponseWritingHeaders { /* connection, … */ } pub

    struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ }
  96. pub struct HttpResponseWritingHeaders { /* connection, … */ } pub

    struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ }
  97. pub struct HttpResponseWritingHeaders { /* connection, … */ } pub

    struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ }
  98. /// The capability to send data with a certain timestamp

    on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time
  99. /// The capability to send data with a certain timestamp

    on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time
  100. /// The capability to send data with a certain timestamp

    on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time
  101. /// The capability to send data with a certain timestamp

    on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time
  102. /// The capability to send data with a certain timestamp

    on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time
  103. /// The capability to send data with a certain timestamp

    on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time
  104. /// The capability to send data with a certain timestamp

    on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time
  105. /// The capability to send data with a certain timestamp

    on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time
  106. MY GROUP IS LOOKING FOR SOFTWARE ENGINEERS AND PHD STUDENTS

    WE WORK WITH RUST HTTPS://WWW.SYSTEMS.ETHZ.CH ANDREA LATTUADA @UTAAL ON TWITTER, GITHUB [email protected] FRANK MCSHERRY, TIMELY DATAFLOW HTTPS://GITHUB.COM/FRANKMCSHERRY/TIMELY-DATAFLOW ANDREA LATTUADA, PROGRAMMABLE SCHEDULING IN A STREAM PROCESSING SYSTEM HTTPS://WWW.RESEARCH-COLLECTION.ETHZ.CH/HANDLE/20.500.11850/155664