¿Utilizando el framework scala actor como cálculo de fork-join?
(1)
¿Es posible, en teoría, utilizar el Marco de actores de Scala para realizar un tipo de cálculo asíncrono de división y conquista de manera similar al marco de unión de JDK 7? Si es así, ¿cómo podría expresar un problema de FJ con el marco, por ejemplo, el concepto de tutorial mergesort? Los códigos de código son bienvenidos.
(Llegué a la idea basada en un video de recursos que tengo en mi otra pregunta relacionada con FJ ).
Scala tiene paralelismo de estilo FJ. Es llamada de futuros y es parte de la biblioteca de actores.
import scala.actors.Future
import scala.actors.Futures._
def mergeSort[A <% Ordered[A]](xs : List[A]) : List[A] = {
// merge is not interesting, it''s sequential. The complexity lies in keeping it tail recursive
def merge[A <% Ordered[A]](accum : List[A], left : List[A], right : List[A]) : List[A] = {
(left, right) match {
case (lhead::ltail, rhead::rtail) =>
if (lhead <= rhead) merge(lhead :: accum, ltail, right)
else merge(rhead :: accum, left, rtail)
case (Nil, _) => accum reverse_::: right
case _ => accum reverse_::: left
}
}
// here''s the parallel sort bit
def sort[A <% Ordered[A]](xs : List[A], length : Int) : List[A] = {
if (length <= 1) xs
else {
val leftLength = length / 2
val rightLength = length - leftLength
val (left, right) = xs splitAt leftLength
// fork
val leftFork = future { sort(left, leftLength) }
val rightFork = future { sort(right, rightLength) }
// join
val leftJoin = leftFork()
val rightJoin = rightFork()
// merge
merge(Nil, leftJoin, rightJoin)
}
}
sort(xs, xs.length)
}
Ahora, al corazón de la pregunta. Si Scala no tuviera futuros, podrías escribir uno tú mismo basado en actores. En efecto. Se vería más o menos así.
import scala.actors.Actor
import scala.actors.Actor._
object MyFuture {
def apply[T](x : => T) : MyFuture[T] = {
val future = new MyFuture[T]
val act = actor {
react {
case sender : Actor => sender ! (future, x)
}
}
act ! self
future
}
}
class MyFuture[A] extends Function0[A] {
me =>
lazy val result = receive {
case (`me`, result) => result.asInstanceOf[A]
}
def apply() = result
}
Y lo usarías así
scala> val x = MyFuture(28 * 1000)
x: Foo.MyFuture[Int] = <function>
scala> x()
res4: Int = 28000