Effect Typing for Scala

A short introduction to the Effects Plugin for Scala

LAMP/LARA Seminar Talk, Lukas Rytz, May 2013

(use arrow keys to navigate)

## Big Picture * A [compiler plugin](https://github.com/lrytz/efftp) for stock Scala 2.10.1 * Entirely based on annotations, no changes to Scala's syntax * Effect-annotated code compiles without the plugin (it's a [pluggable type system](http://bracha.org/pluggableTypesPosition.pdf)) * Currently supports I/O effects, checked exceptions and purity (state effects) * Documentation on the [Github Wiki](https://github.com/lrytz/efftp/wiki)

Just WorksTM in Eclipse

Screenshot Eclipse
## Syntax * Effects are annotated on return types of methods ```scala def inc(i: Int): Int @pure = i + 1 ``` * Effects are inferred if the return type is inferred ```scala def inc(i: Int) = i + 1 // effect is inferred ``` * Methods with a return type, but without effect annotations have an unknown effect ```scala def inc(I: Int): Int = i + 1 // impure! ```
## Multiple Effect Domains * Effect annotations are simply put next to each other ```scala def div(a: Int, b: Int): Int @noIo @mod() @throws[DivByZero] = ... ``` * By default, non-annotated domains are impure * The `@pure` annotation marks a method pure across all effect domains ```scala def div(a: Int, b: Int): Int @pure @throws[DivByZero] = ... ```
## Effect Polymorphism * The effect of a higher-order method usually depends on the effect of its argument: ```scala def h(f: Int => Int): Int @pure(f) = { f(1) } ``` * The _relative effect annotation_ `@pure(f)` marks `h` as pure, up to the effect of `f` (more precisely: `f.apply`) * Relative effects are not tied to function types ```scala def sayHi(g: Greeter, name: String): Unit @pure(g.greet(%)) = { g.greet(name) } ```
## Purity * A method is pure, annotated `@mod()` (or `@pure`) if it does not modify any state that existed before its execution * The annotation `@mod(c)` allows modifying fields of parameter `c` ```scala def inc(c: Counter): Unit @pure @mod(c) = { c.value = c.value + 1 } ``` * Modifying freshly allocated state within a method is not observable, therefore allowed: ```scala def counterFrom(i: Int): Counter @pure = { val c = new Counter for (_ ← 0 until i) inc(c) c } ```
## Freshness / Returned Locality * The `@loc` annotation denotes the locality of the object returned by a method ```scala def inc(c: Counter): Counter @mod(c) @loc(c) = { c.inc() c } ``` * Constructors and factory methods a new object on every invocation, annotated `@loc()` ```scala def counterFromTwo: Counter @pure @loc() = { val c = new Counter c.inc().inc() } ```
# Demo!