Remote Actor + CPS

下記は、あまり嬉しくない。Remote Actor 間でトランポリンする方法を考え中。うーん、reset と shift 以外の制御構造が欲しいと思うのは私だけ?

object RemoteTest {
  import scala.actors.{Actor, AbstractActor}
  import scala.actors.Actor.actor
  import scala.actors.remote.RemoteActor.{alive, register, select}
  import scala.actors.remote.Node
  import scala.util.continuations.{reset, shift, cpsParam}

  def main (args: Array[String]) {
    if (args.length == 1 && args(0) == "test1") {
      runTest1()
    } else if (args.length == 1 && args(0) == "test2") {
      runTest2()
    } else {
      ServerActor.start
    }
  }

  case class  Update(f: Int => Int)
  case object Show

  def runTest1() {
    def update(remoteActor: AbstractActor)(f: Int => Int): Int = {
      remoteActor ! Update(f)
      remoteActor !? Show match {
        case n: Int => n
        case _      => 0
      }
    }

    actor {
      val remoteActor = selectRemoteActor()
      val remoteUpdate = update(remoteActor) _

      println(remoteUpdate(n => n + 1))
      println(remoteUpdate(n => n + 2))
    }
  }

  def runTest2() {
    def update(remoteActor: AbstractActor)(): Int @cpsParam[Int, Int] = shift { k: (Int => Int) =>
      remoteActor ! Update(k)
      remoteActor !? Show match {
        case n: Int => n
        case _      => 0
      }
    }

    actor {
      val remoteActor = selectRemoteActor()
      val remoteUpdate = update(remoteActor) _

      println(reset(remoteUpdate() * 2))
      println(reset(remoteUpdate() * 3))
    }
  }

  def selectRemoteActor(): AbstractActor = select(new Node("127.0.0.1", 10000), 'server)

  object ServerActor extends Actor {
    var counter = 0

    def act() {
      alive(10000)
      register('server, this)

      println("start server")
      loop {
        react {
          case Update(f) => counter = f(counter)
          case Show      => reply(counter)
          case unknown   => println(unknown)
        }
      }
    }
  }
}