Section 4

Section 4.2 – Mutable State

interface State[S] {
  def get(): S
  def set(v: S): Unit
}
def handleState[S, R](init: S) { prog: {State[S]} => R }: R {
  val stateFun: S => R at {prog} =
    try { val res = prog { state }; return box {prog} { (s: S) => res } }
    with state: State[S] {
      def get() { box { (s: S) => (unbox resume(s))(s) } }
      def set(v: S) { box { (_: S) => (unbox resume(()))(v) } }
    };
  return (unbox stateFun)(init)
}
handleState(0) { {s: State[Int]} => println(s.get()); s.set(2); println(s.get()) }

For more details on regions, also see the corresponding regions case study.

def regions1() {
  region r {
    var x in r = 42;
    val t = x;
    x = (t + 1)
  }
}
def regions2() {
  region r {
    var x in r = 42;
    val f: () => Int at {r} = box { () => x };
    (unbox f)()
  }
}
regions2()

Example 4.1

See the scheduler case study

Section 4.4 – Effect Handlers and Object Orientation

Similar examples can be found in the regions case study.

Support code to run the example from Section 2.

interface Console { def println[A](a: A): Unit }
def run[T] { prog : {Console} => T }: T {
  try {
    prog {console}
  } with console: Console {
    def println[A](msg: A) { println(msg); resume(()) }
  }
}
interface Counter {
  def inc(): Unit
  def get(): Int
}
def counterExample { console: Console }: Unit {
  def makeCounter { pool: Region }: Counter at {pool, console} {
    var count in pool = 0;
    def c = new Counter {
      def inc() { console.println(count); count = count + 1 }
      def get() { count }
    };
    return box c
  }

  region r {
    val c1 = makeCounter {r};
    val c2 = makeCounter {r};

    c1.inc();
    c1.inc();
    c2.inc();
    console.println(c1.get());
    console.println(c2.get())
  }
}
run {counterExample}