approximating polymorphic effects with capabilities
play

Approximating Polymorphic Effects with Capabilities Justin Lubin 1 , - PowerPoint PPT Presentation

Approximating Polymorphic Effects with Capabilities Justin Lubin 1 , Darya Melicher 2 , Alex Potanin 3 , Jonathan Aldrich 2 1 University of Chicago, USA 2 Carnegie Mellon University, USA 3 Victoria University of Wellington, NZ Goal Allow secure


  1. Approximating Polymorphic Effects with Capabilities Justin Lubin 1 , Darya Melicher 2 , Alex Potanin 3 , Jonathan Aldrich 2 1 University of Chicago, USA 2 Carnegie Mellon University, USA 3 Victoria University of Wellington, NZ

  2. Goal Allow secure and ergonomic mixing of effect-unannotated code with effect-annotated code in a realistic capability-safe programming language. 2

  3. Background 1. Object Capabilities 2. Effect Systems 3. Capability-Safe Import Semantics 3

  4. 1. Object Capabilities Capabilities Unforgeable objects that give module def logger(myFile : File) particular parts of the code ... access to sensitive resources module def main(platform : Platform) Capability-safe language val myFile = file(platform) val myLogger = logger(myFile) A language in which the only ... way to access sensitive resources is via capabilities 4

  5. 2. Effect Systems Effect system Annotations on methods describing effects they can incur Capability-based effect system Way of formally reasoning about capabilities (awesome!) Downside: verbosity 5

  6. 3. Capability-Safe Import Semantics Prior work (Craig et al.) Import semantics for capability-safe lambda calculus Limitation Does not handle mutable state nor effect polymorphism Our goal Scale up to a more realistic programming language 6

  7. The Problem Effect polymorphism and mutability 7

  8. The Problem resource type Logger effect log def append(contents : String) : {log} Unit Question: How will annotated module def reversePlugin(name : String) code use reversePlugin ? var logger : Logger = ... def setLogger(newLogger : Logger) : Unit Effect polymorphism + logger = newLogger mutability ⇒ log effect could def run(s : String) : String be anything! val t = s.reverse() logger.append(name + “: ” + s + “ -> ” + t) t 8

  9. The Problem resource type Logger effect log def append(contents : String) : {log} Unit Question: How will annotated module def reversePlugin(name : String) code use reversePlugin ? var logger : Logger = ... def setLogger(newLogger : Logger) : Unit Effect polymorphism + logger = newLogger mutability ⇒ log effect could def run(s : String) : String be anything! val t = s.reverse() logger.append(name + “: ” + s + “ -> ” + t) t 9

  10. The Problem resource type Logger effect log def append(contents : String) : {log} Unit Question: How will annotated module def reversePlugin(name : String) code use reversePlugin ? var logger : Logger = ... def setLogger(newLogger : Logger) : Unit Effect polymorphism + logger = newLogger mutability ⇒ log effect could def run(s : String) : String be anything! val t = s.reverse() logger.append(name + “: ” + s + “ -> ” + t) t 10

  11. Solution Quantification lifting 11

  12. Quantification Lifting: Idea resource type Logger resource type Logger[ effect E] effect log def append(contents : String) : {E} Unit def append(contents : String) : {log} Unit module def reversePlugin(name : String) module def reversePlugin[ effect E](name : String) var logger : Logger = ... var logger : Logger[E] = ... def setLogger(newLogger : Logger) : Unit def setLogger(newLogger : Logger[E]) : {E} Unit logger = newLogger logger = newLogger def run(s : String) : String def run(s : String) : {E} String val t = s.reverse() val t = s.reverse() logger.append(name + “: ” + s + “ -> ” + t) logger.append(name + “: ” + s + “ -> ” + t) t t Lift effect polymorphism from inside ML-style module functor to the functor itself ● Collapse each universal effect quantification into single quantified effect E ● Serves as effect bound for all methods in module ○ 12

  13. Quantification Lifting: Idea resource type Logger resource type Logger[ effect E] effect log def append(contents : String) : {E} Unit def append(contents : String) : {log} Unit module def reversePlugin(name : String) module def reversePlugin[ effect E](name : String) var logger : Logger = ... var logger : Logger[E] = ... def setLogger(newLogger : Logger) : Unit def setLogger(newLogger : Logger[E]) : {E} Unit logger = newLogger logger = newLogger def run(s : String) : String def run(s : String) : {E} String val t = s.reverse() val t = s.reverse() logger.append(name + “: ” + s + “ -> ” + t) logger.append(name + “: ” + s + “ -> ” + t) t t Lift effect polymorphism from inside ML-style module functor to the functor itself ● Collapse each universal effect quantification into single quantified effect E ● Serves as effect bound for all methods in module ○ 13

  14. Quantification Lifting: Usage import fileLogger, databaseLogger, reversePlugin val logger1 = fileLogger(...) val logger2 = databaseLogger(...) val plugin = reversePlugin[logger1.log](“archive”) def main() : {logger1.log} Unit plugin.setLogger(logger1) // plugin.setLogger(logger2) <-- not allowed! resource type MyPlugin def setLogger(newLogger : Logger’) : {logger1.log} Unit def run(s : String) : {logger1.log} String resource type Logger’ effect log = {logger1.log} def append(contents : String) : {log} Unit 14

  15. Quantification Lifting: Type-Level Transformation Benefit Don’t need code ahead of time, only type signature ● Dynamic loading (plugins) ● Compiled code ● Third-party libraries Drawback Over-approximation of possibly-incurred effects 15

  16. Related Work Effect inference ● Operates on expressions ● Gives exact bound on effects that can be incurred Algebraic effects ● Has a different goal ● We use the effect system to formally/statically reason about capabilities 16

  17. Conclusion Capabilities are good way of managing non-transitive access to ● system resources Effect systems can formalize capability-based reasoning, but ● can be verbose Craig et al.’s import semantics work great for lambda calculus ● Quantification lifting handles tricky interaction between effect ● polymorphism and mutable state Thanks to Darya Melicher, Alex Potanin, Jonathan Aldrich, CMU, and the NSF! 17

  18. Thank you! resource type Logger resource type Logger[ effect E] effect log def append(contents : String) : {E} Unit def append(contents : String) : {log} Unit module def reversePlugin(name : String) module def reversePlugin[ effect E](name : String) var logger : Logger = ... var logger : Logger[E] = ... def setLogger(newLogger : Logger) : Unit def setLogger(newLogger : Logger[E]) : {E} Unit logger = newLogger logger = newLogger def run(s : String) : String def run(s : String) : {E} String val t = s.reverse() val t = s.reverse() logger.append(name + “: ” + s + “ -> ” + t) logger.append(name + “: ” + s + “ -> ” + t) t t import fileLogger, databaseLogger, reversePlugin resource type MyPlugin val logger1 = fileLogger(...) def setLogger(newLogger : Logger’) : {logger1.log} Unit val logger2 = databaseLogger(...) def run(s : String) : {logger1.log} String val plugin = reversePlugin[logger1.log](“archive”) def main() : {logger1.log} Unit resource type Logger’ plugin.setLogger(logger1) effect log = {logger1.log} // plugin.setLogger(logger2) <-- not allowed! def append(contents : String) : {log} Unit

  19. Extra Slides

  20. Quantification Lifting: Import Bounds resource type Logger resource type Logger[ effect E] effect log def append(contents : String) : {E} Unit def append(contents : String) : {log} Unit module def reversePlugin(name : String) module def reversePlugin[ effect E](name : String) var logger : Logger = ... var logger : Logger[E] = ... def setLogger(newLogger : Logger) : Unit def setLogger(newLogger : Logger[E]) : {E} Unit logger = newLogger logger = newLogger def run(s : String) : String def run(s : String) : {E} String val t = s.reverse() val t = s.reverse() logger.append(name + “: ” + s + “ -> ” + t) logger.append(name + “: ” + s + “ -> ” + t) t t Something to be careful about: bounds on new universally-quantified polymorphism ● Upper bound: Craig et al. import semantics ○ Lower bound: Capability-safety ○ E1

  21. Quantification Lifting: Type-Level Transformation Before: τ 1 → τ 2 After: ∀ ε (L ⊆ ε ⊆ U) . τ 1 → ( τ 2 ) ε E2

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend