trait Stoical
class stoic extends scala.annotation.StaticAnnotation
@stioc
will go exclusively on of method definitions and will ensure that Stoical
objects are captured by the function excepting through the parameters.
- Can not capture values of type
Stoical
. - Can not calling a method that returns a
Stoical
. - Same rules apply for implicits.
The following code shows some simple examples.
class Foo
class Bar extends Stoical
val foo1 = new Foo
def foo2() = new Foo
val bar1 = new Bar
def bar2() = new Bar
def bar3(b: Bar) = ()
@stoic def baz() = {
foo1 // OK
foo2() // OK
bar1 // Disallow
bar2() // Disallow
bar3(new Bar) // OK
}
@stoic def qux(bar1: Bar, bar2: () => Bar, bar3: Bar => ()) = {
foo1 // OK
foo2() // OK
bar1 // OK
bar2() // OK
bar3(new Bar) // OK
}
Stoic functions should have trait just like functions:
trait StoicFunction1[-T, +R] extends Function[T, R] {
@stoic def apply(e: T): R = ???
}
This will allow us to refer to a function that is stoical and to desugar lambdas into anonymous stoic functions.
val f: Int -> Unit = (e: Int) -> println(e)
// would be desugared into
val f: StoicFunction1[Int, Unit] = StoicFunction1[Int, Unit] {
@stoic def apply(e: Int): Unit = println(e)
}
We would start by defining capabilities as being stoical.
trait Capability extends Stoical
We will also need additional constraints such as a pure function can not call a non pure one (unless the bottom capability is available). This is not the focus of this proposal and therfore will not go into details.
After a discussion with Martin the following change in definition fas made:
trait Stoical
and make a synthetic type in the compiler that is outside of theAny
/Nothing
lattice.